2  * ============LICENSE_START=======================================================
 
   4  * ================================================================================
 
   5  * Copyright (C) 2019 Nokia. All rights reserved.
 
   6  * ================================================================================
 
   7  * Licensed under the Apache License, Version 2.0 (the "License");
 
   8  * you may not use this file except in compliance with the License.
 
   9  * You may obtain a copy of the License at
 
  11  *      http://www.apache.org/licenses/LICENSE-2.0
 
  13  * Unless required by applicable law or agreed to in writing, software
 
  14  * distributed under the License is distributed on an "AS IS" BASIS,
 
  15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
  16  * See the License for the specific language governing permissions and
 
  17  * limitations under the License.
 
  18  * ============LICENSE_END=========================================================
 
  21 package org.onap.pnfsimulator.template.search;
 
  23 import com.google.gson.Gson;
 
  24 import com.google.gson.JsonObject;
 
  25 import com.mongodb.BasicDBList;
 
  26 import org.assertj.core.util.Lists;
 
  27 import org.bson.Document;
 
  28 import org.junit.jupiter.api.BeforeEach;
 
  29 import org.junit.jupiter.api.Test;
 
  30 import org.mockito.ArgumentCaptor;
 
  31 import org.mockito.InjectMocks;
 
  32 import org.mockito.Mock;
 
  33 import org.onap.pnfsimulator.template.search.viewmodel.FlatTemplateContent;
 
  34 import org.springframework.data.mongodb.core.MongoTemplate;
 
  35 import org.springframework.data.mongodb.core.query.BasicQuery;
 
  36 import org.springframework.data.mongodb.core.query.Query;
 
  38 import java.util.ArrayList;
 
  39 import java.util.List;
 
  40 import java.util.regex.Pattern;
 
  41 import java.util.stream.Collectors;
 
  43 import static org.assertj.core.api.Java6Assertions.assertThat;
 
  44 import static org.junit.jupiter.api.Assertions.assertThrows;
 
  45 import static org.mockito.ArgumentMatchers.any;
 
  46 import static org.mockito.ArgumentMatchers.anyObject;
 
  47 import static org.mockito.Mockito.times;
 
  48 import static org.mockito.Mockito.verify;
 
  49 import static org.mockito.Mockito.when;
 
  50 import static org.mockito.MockitoAnnotations.initMocks;
 
  53 class TemplateSearchHelperTest {
 
  55     private static final Gson GSON = new Gson();
 
  56     private static final String FLATTENED_TEMPLATES_VIEW = "flatTemplatesView";
 
  59     private MongoTemplate mongoTemplate;
 
  62     private TemplateSearchHelper helper;
 
  64     private static final ArgumentCaptor<Query> QUERY_CAPTOR = ArgumentCaptor.forClass(Query.class);
 
  65     private static final ArgumentCaptor<String> COLLECTION_NAME_CAPTOR = ArgumentCaptor.forClass(String.class);
 
  66     private static final ArgumentCaptor<Class<FlatTemplateContent>> CLASS_TYPE_CAPTOR = ArgumentCaptor.forClass((Class) FlatTemplateContent.class);
 
  75     void shouldReturnNamesForGivenComposedSearchCriteria(){
 
  76         String expectedComposedQueryString = "{\"$and\":[{\"keyValues\":{\"$elemMatch\":{\"k\":{\"$regex\":\":eventName(?:(\\\\[[\\\\d]+\\\\]))?$\",\"$options\":\"iu\"},\"v\":{\"$regex\":\"^\\\\QpnfRegistration_Nokia_5gDu\\\\E$\",\"$options\":\"iu\"}}}},{\"keyValues\":{\"$elemMatch\":{\"k\":{\"$regex\":\":sequence(?:(\\\\[[\\\\d]+\\\\]))?$\",\"$options\":\"iu\"},\"v\":1.0}}}]}";
 
  77         Query expectedQuery = new BasicQuery(expectedComposedQueryString);
 
  79         String composedCriteriaInputJson = "{\"eventName\": \"pnfRegistration_Nokia_5gDu\", \"sequence\": 1}";
 
  80         JsonObject composedCriteriaObject = GSON.fromJson(composedCriteriaInputJson, JsonObject.class);
 
  82         when(mongoTemplate.find(any(Query.class), anyObject(), any(String.class))).thenReturn(Lists.newArrayList(new FlatTemplateContent("sampleId1", null), new FlatTemplateContent("sampleId2", null)));
 
  84         List<String> idsOfDocumentMatchingCriteria = helper.getIdsOfDocumentMatchingCriteria(composedCriteriaObject);
 
  86         assertThat(idsOfDocumentMatchingCriteria).containsOnly("sampleId1", "sampleId2");
 
  87         verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture());
 
  88         assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQuery.toString());
 
  89         assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW);
 
  90         assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class);
 
  94     void shouldReturnTemplatesAccordingToGivenSearchCriteria() {
 
  95         Query expectedQueryStructure = new BasicQuery("{\"$and\":[{\"keyValues\": { \"$elemMatch\" : { \"k\" : { \"$regex\" : \":domain(?:(\\\\[[\\\\d]+\\\\]))?$\", \"$options\" : \"iu\" }, \"v\" : { \"$regex\" : \"^\\\\Qnotification\\\\E$\", \"$options\" : \"iu\" }}}}]}");
 
  97         helper.getIdsOfDocumentMatchingCriteria(GSON.fromJson("{\"domain\": \"notification\"}", JsonObject.class));
 
 100         verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture());
 
 102         assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQueryStructure.toString());
 
 103         assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW);
 
 104         assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class);
 
 108     void shouldGetQueryForEmptyJson(){
 
 109         JsonObject jsonObject = GSON.fromJson("{}", JsonObject.class);
 
 111         String expectedComposedQueryString = "{}";
 
 112         Query expectedQuery = new BasicQuery(expectedComposedQueryString);
 
 114         helper.getIdsOfDocumentMatchingCriteria(jsonObject);
 
 116         verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture());
 
 117         Query queryBasedOnCriteria = QUERY_CAPTOR.getValue();
 
 119         assertThat(QUERY_CAPTOR.getValue().toString()).isEqualTo(expectedQuery.toString());
 
 120         assertThat(COLLECTION_NAME_CAPTOR.getValue()).isEqualTo(FLATTENED_TEMPLATES_VIEW);
 
 121         assertThat(CLASS_TYPE_CAPTOR.getValue()).isEqualTo(FlatTemplateContent.class);
 
 126     void shouldGetQueryWithAllTypeValues(){
 
 127         JsonObject jsonObject = GSON.fromJson("{\"stringKey\": \"stringValue\", \"numberKey\": 16.00, \"boolKey\": false}", JsonObject.class);
 
 129         helper.getIdsOfDocumentMatchingCriteria(jsonObject);
 
 131         verify(mongoTemplate, times(1)).find(QUERY_CAPTOR.capture(), CLASS_TYPE_CAPTOR.capture(), COLLECTION_NAME_CAPTOR.capture());
 
 132         Query queryBasedOnCriteria = QUERY_CAPTOR.getValue();
 
 134         assertThat(queryBasedOnCriteria.getQueryObject().get("$and")).isInstanceOf(List.class);
 
 135         List<Document> conditionDocuments = new ArrayList<>((List<Document>) queryBasedOnCriteria.getQueryObject().get("$and"));
 
 136         List<Document> conditions = conditionDocuments.stream().map(el -> (Document) el.get("keyValues")).map(el -> (Document) el.get("$elemMatch")).collect(Collectors.toList());
 
 138         assertThat(conditionDocuments).hasSize(3);
 
 139         assertJsonPreparedKeyHasCorrectStructure(conditions.get(0), "stringKey");
 
 140         assertThat(conditions.get(0).get("v").toString()).isEqualTo(TemplateSearchHelper.getCaseInsensitive("^\\QstringValue\\E$").toString());
 
 142         assertJsonPreparedKeyHasCorrectStructure(conditions.get(1), "numberKey");
 
 143         assertThat(conditions.get(1).get("v")).isEqualTo(16.0);
 
 145         assertJsonPreparedKeyHasCorrectStructure(conditions.get(2), "boolKey");
 
 146         assertThat(conditions.get(2).get("v")).isEqualTo("false");
 
 150     void shouldThrowExceptionWhenNullIsPresentAsCriteriaValue(){
 
 151         JsonObject jsonObject = GSON.fromJson("{\"stringKey\": \"stringValue\", \"nullKey\": null}", JsonObject.class);
 
 153         assertThrows(IllegalJsonValueException.class, () -> helper.getIdsOfDocumentMatchingCriteria(jsonObject));
 
 156     private void assertJsonPreparedKeyHasCorrectStructure(Document actual, String expectedPattern){
 
 157         assertThat(actual.get("k").toString()).isEqualTo(Pattern.compile(String.format(":%s(?:(\\[[\\d]+\\]))?$", expectedPattern)).toString());