Untitled
unknown
plain_text
8 months ago
19 kB
7
Indexable
import io.cucumber.java.en.Then;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Step definitions for testing the NNS Recommendations Personalized API.
*/
public class NnsRecommendationsStepDefinitions {
// Required fields in the response
private static final String[] REQUIRED_RECOMMENDATIONS_FIELDS = {
"type", "uiHint", "vodOutOfWindow", "name", "twcTvNetworkDisplayMode",
"results", "num_categories", "total_results", "start_index",
"num_results", "max_results", "dsQueryId", "curationType", "dynamicUris"
};
// Required fields in each result item (common fields for both event and episode_list)
private static final String[] REQUIRED_RESULT_FIELDS = {
"type", "alphaSortOn", "availableOutOfHome", "details", "title", "uri", "skeletonShelf"
};
// Required fields specific to event type
private static final String[] REQUIRED_EVENT_FIELDS = {
"tmsProgramIds", "providerAssetIds", "image_uri", "network"
};
// Required fields specific to episode_list type
private static final String[] REQUIRED_EPISODE_LIST_FIELDS = {
"tmsSeriesId", "tmsSeriesIdStr", "tmsGuideServiceIds", "image_uri", "network"
};
// Required fields in details object for event
private static final String[] REQUIRED_EVENT_DETAILS_FIELDS = {
"genres", "allRatings", "allVPPs", "allIpVPPs", "entitled",
"tvodEntitled", "linearEntitledIp", "linearEntitledQam"
};
// Required fields in details object for episode_list
private static final String[] REQUIRED_EPISODE_LIST_DETAILS_FIELDS = {
"num_assets", "totalEpisodes", "latest_episode", "allRatings", "allVPPs", "allIpVPPs"
};
// Required fields in network object
private static final String[] REQUIRED_NETWORK_FIELDS = {
"callsign", "image_uri", "name", "product_provider"
};
/**
* Tests the NNS Recommendations Personalized API with the given parameters and compares with Search API.
*
* @param division The division parameter
* @param vodId The vodId parameter
* @param lineup The lineup parameter
* @param useridhash The useridhash parameter
*/
@Then("The NNS recommendations personalized call with division {string}, vodId {string}, lineup {string}, and useridhash {string} should return expected data structure")
public void request_and_verify_nns_recommendations_personalized(String division, String vodId, String lineup, String useridhash) {
// Create the request parameters for NNS
RequestParams params = new RequestParams();
params.add("division", division);
params.add("vodId", vodId);
params.add("lineup", lineup);
params.add("path", "1757001972");
params.add("useridhash", useridhash);
params.add("recommendationKey", "HNAV_VOD_Free_");
params.add("profile", "{client_nns_profile}");
params.add("cacheID", "280");
params.add("application", "VOD_PORTAL");
params.add("profileConfigurationEnablePersonalizedRecommendations", "true");
params.add("profileConfigurationHttpCachingStrategy", "MAX_AGE");
params.add("profileConfigurationIncludeNielsenReporting", "true");
params.add("profileConfigurationSearchUseBkm", "true");
params.add("profileConfigurationTwctvClientUseActionGroupsWholeApp", "true");
params.add("tvodRent", "true");
params.add("tvodWatch", "true");
params.add("cdvrEnabled", "true");
params.add("deviceLocation", "In_Home");
params.add("watchOnDemand", "true");
params.add("hideOnDemand", "false");
params.add("watchLive", "true");
// Add cookie header
Map<String, String> headers = new HashMap<>();
headers.put("Cookie", "dla_marker=9febad42-bf50-4142-8ce1-812361e31a4b");
// Make the NNS API call
ServiceApiResponse nnsResponse = restNNS().apiRecommendationsPersonalized(params, headers).get();
// Verify the response status
assertTrue("NNS recommendations personalized API call failed with status: " + nnsResponse.status() +
" and TXID: " + nnsResponse.txId(), nnsResponse.isSuccess());
// Parse the JSON response
JSON nnsJson = nnsResponse.json();
// Log response for debugging
Logger.info("NNS API Response: " + nnsJson.toString());
// Validate the required fields in the response
validateRequiredFields(nnsJson, REQUIRED_RECOMMENDATIONS_FIELDS, "Root object");
// Validate the results array
validateResultsArray(nnsJson.get("results"));
// Additional validation
assertEquals("Expected name to be 'Personalized'", "Personalized", nnsJson.getString("name"));
assertEquals("Expected curationType to be 'personalized'", "personalized", nnsJson.getString("curationType"));
assertTrue("Expected at least one dynamic URI", nnsJson.getArraySize("dynamicUris") > 0);
// Extract tmsProgramIds from NNS response for comparison with Search API
List<String> tmsProgramIds = extractTmsProgramIds(nnsJson.get("results"));
// If we have tmsProgramIds, make the search API call for comparison
if (!tmsProgramIds.isEmpty()) {
compareWithSearchApi(tmsProgramIds, division, vodId, lineup);
}
}
/**
* Validates that the given JSON object contains all required fields.
*/
private void validateRequiredFields(JSON json, String[] requiredFields, String objectName) {
for (String field : requiredFields) {
assertTrue(objectName + " missing required field: " + field, json.hasField(field));
}
}
/**
* Validates the results array in the response.
*/
private void validateResultsArray(JSON results) {
assertTrue("Results should be an array", results.isArray());
assertTrue("Results array should not be empty", results.size() > 0);
boolean foundEventType = false;
boolean foundEpisodeListType = false;
// Validate each result item
for (int i = 0; i < results.size(); i++) {
JSON result = results.get(i);
// Validate common fields for all result types
validateRequiredFields(result, REQUIRED_RESULT_FIELDS, "Result item " + i);
// Validate type-specific fields and track if we've found each type
String type = result.getString("type");
if ("event".equals(type)) {
foundEventType = true;
validateEventType(result, i);
} else if ("episode_list".equals(type)) {
foundEpisodeListType = true;
validateEpisodeListType(result, i);
}
}
// Ensure we've found at least one of each type for comprehensive validation
assertTrue("No 'event' type found in results", foundEventType);
assertTrue("No 'episode_list' type found in results", foundEpisodeListType);
}
/**
* Validates an event type result.
*/
private void validateEventType(JSON event, int index) {
// Validate event-specific fields
validateRequiredFields(event, REQUIRED_EVENT_FIELDS, "Event " + index);
// Validate details object
JSON details = event.get("details");
validateRequiredFields(details, REQUIRED_EVENT_DETAILS_FIELDS, "Event " + index + " details");
// Validate genres array
JSON genres = details.get("genres");
assertTrue("Genres should be an array", genres.isArray());
if (genres.size() > 0) {
for (int i = 0; i < genres.size(); i++) {
assertTrue("Genre " + i + " should have a name", genres.get(i).hasField("name"));
}
}
// Validate arrays
validateArrayField(details, "allRatings");
validateArrayField(details, "allVPPs");
validateArrayField(details, "allIpVPPs");
validateArrayField(event, "tmsProgramIds");
validateArrayField(event, "providerAssetIds");
validateArrayField(event, "tmsGuideServiceIds", true); // Optional field
validateArrayField(event, "ipTmsGuideServiceIds", true); // Optional field
// Validate network
validateNetwork(event.get("network"));
// Validate streamList if present
if (event.hasField("streamList")) {
validateStreamList(event.get("streamList"));
}
}
/**
* Validates an episode_list type result.
*/
private void validateEpisodeListType(JSON episodeList, int index) {
// Validate episode_list-specific fields
validateRequiredFields(episodeList, REQUIRED_EPISODE_LIST_FIELDS, "Episode list " + index);
// Validate details object
JSON details = episodeList.get("details");
validateRequiredFields(details, REQUIRED_EPISODE_LIST_DETAILS_FIELDS, "Episode list " + index + " details");
// Validate latest_episode
validateLatestEpisode(details.get("latest_episode"));
// Validate arrays
validateArrayField(details, "allRatings");
validateArrayField(details, "allVPPs");
validateArrayField(details, "allIpVPPs");
validateArrayField(episodeList, "tmsGuideServiceIds");
validateArrayField(episodeList, "ipTmsGuideServiceIds");
// Validate network
validateNetwork(episodeList.get("network"));
}
/**
* Validates the latest_episode object in an episode_list.
*/
private void validateLatestEpisode(JSON latestEpisode) {
assertTrue("Latest episode should have type field", latestEpisode.hasField("type"));
assertTrue("Latest episode should have details field", latestEpisode.hasField("details"));
assertTrue("Latest episode should have title field", latestEpisode.hasField("title"));
// Validate latest episode details
JSON details = latestEpisode.get("details");
assertTrue("Latest episode details should have genres field", details.hasField("genres"));
// Validate genres array
JSON genres = details.get("genres");
assertTrue("Genres should be an array", genres.isArray());
if (genres.size() > 0) {
for (int i = 0; i < genres.size(); i++) {
assertTrue("Genre " + i + " should have a name", genres.get(i).hasField("name"));
}
}
// Validate network if present
if (latestEpisode.hasField("network")) {
validateNetwork(latestEpisode.get("network"));
}
// Validate streamList if present
if (latestEpisode.hasField("streamList")) {
validateStreamList(latestEpisode.get("streamList"));
}
}
/**
* Validates the network object.
*/
private void validateNetwork(JSON network) {
validateRequiredFields(network, REQUIRED_NETWORK_FIELDS, "Network");
// Validate product_providers array if present
if (network.hasField("product_providers")) {
validateArrayField(network, "product_providers");
}
}
/**
* Validates the stream list array.
*/
private void validateStreamList(JSON streamList) {
assertTrue("Stream list should be an array", streamList.isArray());
for (int i = 0; i < streamList.size(); i++) {
JSON stream = streamList.get(i);
// Validate required fields
assertTrue("Stream " + i + " missing type field", stream.hasField("type"));
// Validate streamProperties if present
if (stream.hasField("streamProperties")) {
JSON props = stream.get("streamProperties");
assertTrue("Stream properties should have entitled field", props.hasField("entitled"));
// Validate nielsenReporting if present
if (props.hasField("nielsenReporting")) {
JSON nielsen = props.get("nielsenReporting");
validateArrayField(nielsen, "metrics");
validateArrayField(nielsen, "locations");
}
}
// Validate network if present
if (stream.hasField("network")) {
validateNetwork(stream.get("network"));
}
}
}
/**
* Validates that the given field is an array.
*/
private void validateArrayField(JSON json, String fieldName) {
validateArrayField(json, fieldName, false);
}
/**
* Validates that the given field is an array.
*
* @param json The JSON object containing the field
* @param fieldName The name of the field to validate
* @param optional Whether the field is optional
*/
private void validateArrayField(JSON json, String fieldName, boolean optional) {
if (json.hasField(fieldName)) {
Object field = json.get(fieldName);
assertTrue(fieldName + " is not an array", (field instanceof JSON) && ((JSON) field).isArray());
} else if (!optional) {
fail("Required array field " + fieldName + " is missing");
}
}
/**
* Extracts all tmsProgramIds from the results array.
*/
private List<String> extractTmsProgramIds(JSON results) {
List<String> tmsProgramIds = new ArrayList<>();
for (int i = 0; i < results.size(); i++) {
JSON result = results.get(i);
String type = result.getString("type");
if ("event".equals(type) && result.hasField("tmsProgramIds")) {
JSON ids = result.get("tmsProgramIds");
for (int j = 0; j < ids.size(); j++) {
tmsProgramIds.add(ids.getString(j));
}
} else if ("episode_list".equals(type) && result.hasField("details")) {
JSON details = result.get("details");
if (details.hasField("latest_episode")) {
JSON latestEpisode = details.get("latest_episode");
if (latestEpisode.hasField("tmsProgramIds")) {
JSON ids = latestEpisode.get("tmsProgramIds");
for (int j = 0; j < ids.size(); j++) {
tmsProgramIds.add(ids.getString(j));
}
}
}
}
}
return tmsProgramIds;
}
/**
* Compares the NNS response with the Search API response.
*/
private void compareWithSearchApi(List<String> tmsProgramIds, String division, String vodId, String lineup) {
// Build search API request
RequestParams searchParams = new RequestParams();
searchParams.add("dynListKey", "HNAV_VOD_Free_");
searchParams.add("callerAppName", "TWCTV");
searchParams.add("offset", "0");
searchParams.add("maxResults", "15");
searchParams.add("direction", "FORWARD");
searchParams.add("sortType", "PERSONALIZED");
searchParams.add("programAttribute", "HighDefinition,StdDefinition");
searchParams.add("alAdultCont", "false");
searchParams.add("contType", "SERIES,MOVIE,PROGRAM");
searchParams.add("linTRange", "NOW_TO_13_DAYS_MIDNIGHT");
searchParams.add("exclSeriesEpisodes", "false");
searchParams.add("vodLicWind", "IN_WINDOW");
searchParams.add("filterPPV", "true");
searchParams.add("filterOutSVOD", "false");
searchParams.add("sppEnabled", "false");
searchParams.add("incLetInd", "false");
searchParams.add("linTRangeEndMs", "0");
searchParams.add("linTRangeStartMs", "0");
searchParams.add("billingAccountId", "8347100040106596");
searchParams.add("billingDivision", "LNK.8347");
searchParams.add("includeUnmapped", "true");
searchParams.add("locDiv", division);
searchParams.add("locLup", lineup);
searchParams.add("contSourLin", "IP");
searchParams.add("contSourVod", "IP");
searchParams.add("contSourTVod", "BOTH_AND");
searchParams.add("vodDiv", division);
searchParams.add("includeSchedule", "false");
searchParams.add("resultFieldSet", "IDS");
searchParams.add("groupingField", "GROUP_ID");
// Make the Search API call
ServiceApiResponse searchResponse = restSearch().apiAssetSearchDynamicList(searchParams).get();
// Verify the response status
assertTrue("Search API call failed with status: " + searchResponse.status() +
" and TXID: " + searchResponse.txId(), searchResponse.isSuccess());
// Parse the JSON response
JSON searchJson = searchResponse.json();
// Log response for debugging
Logger.info("Search API Response: " + searchJson.toString());
// Extract tmsIds from search response
List<String> searchTmsIds = extractSearchTmsIds(searchJson);
// Compare TMS IDs from both responses
Logger.info("Comparing TMS IDs between NNS and Search APIs");
Logger.info("NNS TMS IDs: " + tmsProgramIds);
Logger.info("Search TMS IDs: " + searchTmsIds);
// Validate that at least some of the IDs match (not all will match exactly)
boolean foundMatch = false;
for (String nnsId : tmsProgramIds) {
if (searchTmsIds.contains(nnsId)) {
foundMatch = true;
break;
}
}
assertTrue("No matching TMS IDs found between NNS and Search APIs", foundMatch);
}
/**
* Extracts tmsIds from the Search API response.
*/
private List<String> extractSearchTmsIds(JSON searchJson) {
List<String> tmsIds = new ArrayList<>();
if (searchJson.hasField("assets")) {
JSON assets = searchJson.get("assets");
for (int i = 0; i < assets.size(); i++) {
JSON asset = assets.get(i);
if (asset.hasField("tmsId")) {
tmsIds.add(asset.getString("tmsId"));
}
}
}
return tmsIds;
}
}Editor is loading...
Leave a Comment