Untitled
unknown
plain_text
20 days ago
19 kB
4
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