Support updated data types in service import
[sdc.git] / catalog-model / src / test / java / org / openecomp / sdc / be / model / operations / impl / ModelOperationTest.java
1 /*
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2021 Nordix Foundation
4  *  ================================================================================
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *        http://www.apache.org/licenses/LICENSE-2.0
10  *  Unless required by applicable law or agreed to in writing, software
11  *  distributed under the License is distributed on an "AS IS" BASIS,
12  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *  See the License for the specific language governing permissions and
14  *  limitations under the License.
15  *
16  *  SPDX-License-Identifier: Apache-2.0
17  *  ============LICENSE_END=========================================================
18  */
19 package org.openecomp.sdc.be.model.operations.impl;
20
21 import static org.assertj.core.api.Assertions.assertThat;
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertThrows;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.mockito.ArgumentMatchers.any;
28 import static org.mockito.ArgumentMatchers.anyList;
29 import static org.mockito.ArgumentMatchers.anyMap;
30 import static org.mockito.ArgumentMatchers.anyString;
31 import static org.mockito.ArgumentMatchers.eq;
32 import static org.mockito.Mockito.mock;
33 import static org.mockito.Mockito.never;
34 import static org.mockito.Mockito.times;
35 import static org.mockito.Mockito.verify;
36 import static org.mockito.Mockito.when;
37 import static org.openecomp.sdc.be.model.operations.impl.ModelOperation.ADDITIONAL_TYPE_DEFINITIONS_PATH;
38
39 import fj.data.Either;
40 import java.io.IOException;
41 import java.nio.charset.StandardCharsets;
42 import java.nio.file.Files;
43 import java.nio.file.Path;
44 import java.util.ArrayList;
45 import java.util.Collections;
46 import java.util.List;
47 import java.util.Map;
48 import java.util.Optional;
49 import java.util.TreeMap;
50 import java.util.stream.Stream;
51 import org.apache.commons.lang3.tuple.ImmutablePair;
52 import org.junit.jupiter.api.BeforeAll;
53 import org.junit.jupiter.api.BeforeEach;
54 import org.junit.jupiter.api.Test;
55 import org.mockito.ArgumentCaptor;
56 import org.mockito.InjectMocks;
57 import org.mockito.Mock;
58 import org.mockito.MockitoAnnotations;
59 import org.openecomp.sdc.be.dao.api.ActionStatus;
60 import org.openecomp.sdc.be.dao.cassandra.ToscaModelImportCassandraDao;
61 import org.openecomp.sdc.be.dao.graph.datatype.GraphEdge;
62 import org.openecomp.sdc.be.dao.graph.datatype.GraphRelation;
63 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphDao;
64 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphGenericDao;
65 import org.openecomp.sdc.be.dao.janusgraph.JanusGraphOperationStatus;
66 import org.openecomp.sdc.be.dao.jsongraph.GraphVertex;
67 import org.openecomp.sdc.be.dao.jsongraph.types.VertexTypeEnum;
68 import org.openecomp.sdc.be.dao.neo4j.GraphEdgeLabels;
69 import org.openecomp.sdc.be.data.model.ToscaImportByModel;
70 import org.openecomp.sdc.be.datatypes.enums.GraphPropertyEnum;
71 import org.openecomp.sdc.be.datatypes.enums.ModelTypeEnum;
72 import org.openecomp.sdc.be.datatypes.enums.NodeTypeEnum;
73 import org.openecomp.sdc.be.model.Model;
74 import org.openecomp.sdc.be.model.ModelTestBase;
75 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.ModelOperationExceptionSupplier;
76 import org.openecomp.sdc.be.model.jsonjanusgraph.operations.exception.OperationException;
77 import org.openecomp.sdc.be.model.normatives.ElementTypeEnum;
78 import org.openecomp.sdc.be.model.operations.api.DerivedFromOperation;
79 import org.openecomp.sdc.be.resources.data.ModelData;
80 import org.springframework.test.context.ContextConfiguration;
81
82 @ContextConfiguration("classpath:application-context-test.xml")
83 class ModelOperationTest extends ModelTestBase {
84
85     private static final String modelName = "ETSI-SDC-MODEL-TEST";
86     @InjectMocks
87     private ModelOperation modelOperation;
88     @Mock
89     private JanusGraphGenericDao janusGraphGenericDao;
90     @Mock
91     private JanusGraphDao janusGraphDao;
92     @Mock
93     private ToscaModelImportCassandraDao toscaModelImportCassandraDao;
94     @Mock
95     private DerivedFromOperation derivedFromOperation;
96
97     @BeforeAll
98     static void beforeAllInit() {
99         init();
100     }
101
102     @BeforeEach
103     void beforeEachInit() {
104         MockitoAnnotations.openMocks(this);
105     }
106
107     @Test
108     void createModelSuccessTest() {
109         final ModelData modelData = new ModelData(modelName, UniqueIdBuilder.buildModelUid(modelName), ModelTypeEnum.NORMATIVE);
110         when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.left(modelData));
111         final Model createdModel = modelOperation.createModel(new Model(modelName, ModelTypeEnum.NORMATIVE), false);
112         assertThat(createdModel).isNotNull();
113         assertThat(createdModel.getName()).isEqualTo(modelName);
114     }
115
116     @Test
117     void createDerivedModelSuccessTest() {
118         final String derivedModelName = "derivedModel";
119         final ModelData modelData = new ModelData(derivedModelName, UniqueIdBuilder.buildModelUid(derivedModelName), ModelTypeEnum.NORMATIVE);
120         when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.left(modelData));
121
122         final GraphVertex modelVertex = new GraphVertex();
123         modelVertex.addMetadataProperty(GraphPropertyEnum.NAME, "baseModel");
124         modelVertex.addMetadataProperty(GraphPropertyEnum.MODEL_TYPE, ModelTypeEnum.NORMATIVE.getValue());
125         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(Collections.singletonList(modelVertex)));
126         when(janusGraphGenericDao.getChild(eq("uid"), anyString(), eq(GraphEdgeLabels.DERIVED_FROM), eq(NodeTypeEnum.Model),
127             eq(ModelData.class))).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
128         when(derivedFromOperation.addDerivedFromRelation("model.derivedModel", "model.baseModel", NodeTypeEnum.Model)).thenReturn(
129             Either.left(new GraphRelation()));
130
131         final Model createdModel = modelOperation.createModel(new Model(derivedModelName, modelName, ModelTypeEnum.NORMATIVE), false);
132         assertThat(createdModel).isNotNull();
133         assertThat(createdModel.getName()).isEqualTo(derivedModelName);
134     }
135
136     @Test
137     void createModelFailWithModelAlreadyExistTest() {
138         when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.right(JanusGraphOperationStatus.JANUSGRAPH_SCHEMA_VIOLATION));
139         final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
140         assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
141     }
142
143     @Test
144     void createModelFailTest() {
145         when(janusGraphGenericDao.createNode(any(), any())).thenReturn(Either.right(JanusGraphOperationStatus.GRAPH_IS_NOT_AVAILABLE));
146         final var model = new Model(modelName, ModelTypeEnum.NORMATIVE);
147         assertThrows(OperationException.class, () -> modelOperation.createModel(model, false));
148     }
149
150     @Test
151     void createModelImportsSuccessTest() {
152         var modelId = "modelId";
153         var contentEntry1 = "contentEntry1";
154         var pathEntry1 = "entry1";
155         var contentEntry2 = "contentEntry2";
156         var pathEntry2 = "entry2/path";
157         final Map<String, byte[]> zipContent = new TreeMap<>();
158         zipContent.put(pathEntry1, contentEntry1.getBytes(StandardCharsets.UTF_8));
159         zipContent.put(pathEntry2, contentEntry2.getBytes(StandardCharsets.UTF_8));
160
161         modelOperation.createModelImports(modelId, zipContent);
162
163         final var toscaImport1 = new ToscaImportByModel();
164         toscaImport1.setModelId(modelId);
165         toscaImport1.setContent(contentEntry1);
166         toscaImport1.setFullPath(pathEntry1);
167         final var toscaImport2 = new ToscaImportByModel();
168         toscaImport2.setModelId(modelId);
169         toscaImport2.setContent(contentEntry2);
170         toscaImport2.setFullPath(pathEntry2);
171         final List<ToscaImportByModel> toscaImportByModelList = List.of(toscaImport1, toscaImport2);
172
173         verify(toscaModelImportCassandraDao).replaceImports(modelId, toscaImportByModelList);
174     }
175
176     @Test
177     void createModelImportsTest_emptyZipContent() {
178         var modelId = "modelId";
179         modelOperation.createModelImports(modelId, Collections.emptyMap());
180         verify(toscaModelImportCassandraDao, never()).replaceImports(eq(modelId), anyList());
181         modelOperation.createModelImports(modelId, null);
182         verify(toscaModelImportCassandraDao, never()).replaceImports(eq(null), anyList());
183     }
184
185     @Test
186     void findModelVertexSuccessTest() {
187         final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
188         final GraphVertex expectedVertex = new GraphVertex();
189         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
190         var modelName = "modelName";
191         final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
192         assertTrue(modelVertexByNameOpt.isPresent());
193         assertEquals(expectedVertex, modelVertexByNameOpt.get());
194         final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
195         assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
196         assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
197     }
198
199     @Test
200     void findModelVertexTest_modelNotFound() {
201         final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
202         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
203             .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
204         var modelName = "modelName";
205
206         final Optional<GraphVertex> modelVertexByNameOpt = modelOperation.findModelVertexByName(modelName);
207
208         assertTrue(modelVertexByNameOpt.isEmpty());
209         final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
210         assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
211         assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
212     }
213
214     @Test
215     void findModelVertexTest_janusGraphError() {
216         final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
217         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
218             .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
219         var modelName = "modelName";
220
221         final var actualException = assertThrows(OperationException.class, () -> modelOperation.findModelVertexByName(modelName));
222
223         assertEquals(ActionStatus.GENERAL_ERROR, actualException.getActionStatus());
224         final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
225         assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
226         assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
227     }
228
229     @Test
230     void findModelVertexTest_emptyOrNullModelName() {
231         assertTrue(modelOperation.findModelVertexByName("").isEmpty());
232         assertTrue(modelOperation.findModelVertexByName(null).isEmpty());
233     }
234
235     @Test
236     void findModelByNameSuccessTest() {
237         final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
238         var modelName = "modelName";
239         final GraphVertex expectedVertex = mock(GraphVertex.class);
240         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
241         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
242         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture())).thenReturn(Either.left(List.of(expectedVertex)));
243         when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
244             GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
245         final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
246
247         final Map<GraphPropertyEnum, Object> value = mapArgumentCaptor.getValue();
248         assertEquals(modelName, value.get(GraphPropertyEnum.NAME));
249         assertEquals(UniqueIdBuilder.buildModelUid(modelName), value.get(GraphPropertyEnum.UNIQUE_ID));
250
251         final Model expectedModel = new Model(modelName, ModelTypeEnum.NORMATIVE);
252         assertTrue(modelByNameOpt.isPresent());
253         assertEquals(expectedModel, modelByNameOpt.get());
254     }
255
256     @Test
257     void findModelByNameTest_modelNameNotFound() {
258         final ArgumentCaptor<Map<GraphPropertyEnum, Object>> mapArgumentCaptor = ArgumentCaptor.forClass(Map.class);
259         var modelName = "modelName";
260         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), mapArgumentCaptor.capture()))
261             .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
262         final Optional<Model> modelByNameOpt = modelOperation.findModelByName(modelName);
263         assertTrue(modelByNameOpt.isEmpty());
264     }
265
266     @Test
267     void findModelByNameTest_emptyOrNullModelName() {
268         assertTrue(modelOperation.findModelByName("").isEmpty());
269         assertTrue(modelOperation.findModelByName(null).isEmpty());
270     }
271
272     @Test
273     void findAllModelsSuccessTest() {
274         final GraphVertex expectedVertex = mock(GraphVertex.class);
275         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
276         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE.getValue());
277         when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(List.of(expectedVertex)));
278         when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
279             GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
280
281         final List<Model> actualModelList = modelOperation.findAllModels();
282         assertFalse(actualModelList.isEmpty());
283         assertEquals(1, actualModelList.size());
284         assertEquals(modelName, actualModelList.get(0).getName());
285     }
286
287     @Test
288     void findAllModelsTest_noModelsFound() {
289         when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap())).thenReturn(Either.left(Collections.emptyList()));
290         final List<Model> actualModelList = modelOperation.findAllModels();
291         assertTrue(actualModelList.isEmpty());
292     }
293
294     @Test
295     void findAllModelsTest_janusGraphNotFound() {
296         when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
297             .thenReturn(Either.right(JanusGraphOperationStatus.NOT_FOUND));
298         final List<Model> actualModelList = modelOperation.findAllModels();
299         assertTrue(actualModelList.isEmpty());
300     }
301
302     @Test
303     void findAllModelsTest_janusGraphError() {
304         when(janusGraphDao.getByCriteria(VertexTypeEnum.MODEL, Collections.emptyMap()))
305             .thenReturn(Either.right(JanusGraphOperationStatus.GENERAL_ERROR));
306         final var actualException = assertThrows(OperationException.class, () -> modelOperation.findAllModels());
307         final var expectedException = ModelOperationExceptionSupplier.failedToRetrieveModels(JanusGraphOperationStatus.GENERAL_ERROR).get();
308         assertEquals(expectedException.getMessage(), actualException.getMessage());
309     }
310
311     @Test
312     void findAllModelImportsTest() {
313         //given
314         final var modelName = "modelName";
315         final var parentModelName = "parentModelName";
316         final GraphVertex expectedVertex = mock(GraphVertex.class);
317         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.NAME)).thenReturn(modelName);
318         when(expectedVertex.getMetadataProperty(GraphPropertyEnum.MODEL_TYPE)).thenReturn(ModelTypeEnum.NORMATIVE_EXTENSION.getValue());
319         when(janusGraphDao.getByCriteria(eq(VertexTypeEnum.MODEL), anyMap())).thenReturn(Either.left(List.of(expectedVertex)));
320
321         final var modelData = new ModelData(parentModelName, parentModelName, ModelTypeEnum.NORMATIVE);
322         final ImmutablePair<ModelData, GraphEdge> modelDataGraphEdgePair = new ImmutablePair<>(modelData, null);
323
324         when(janusGraphGenericDao.getChild(UniqueIdBuilder.getKeyByNodeType(NodeTypeEnum.Model), UniqueIdBuilder.buildModelUid(modelName),
325             GraphEdgeLabels.DERIVED_FROM, NodeTypeEnum.Model, ModelData.class)).thenReturn(Either.left(modelDataGraphEdgePair));
326
327         final ArrayList<ToscaImportByModel> childModelImportList = new ArrayList<>();
328         childModelImportList.add(createModelImport(modelName, "anyPath1"));
329         childModelImportList.add(createModelImport(modelName, "anyPath2"));
330         when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(new ArrayList<>(childModelImportList));
331         final ArrayList<ToscaImportByModel> parentModelImportList = new ArrayList<>();
332         parentModelImportList.add(createModelImport(parentModelName, "anyPath1"));
333         parentModelImportList.add(createModelImport(parentModelName, "anyPath2"));
334         when(toscaModelImportCassandraDao.findAllByModel(parentModelName)).thenReturn(parentModelImportList);
335
336         //when
337         final List<ToscaImportByModel> actualModelImportList = modelOperation.findAllModelImports(modelName, true);
338
339         //then
340         assertFalse(actualModelImportList.isEmpty());
341         assertEquals(childModelImportList.size() + parentModelImportList.size(), actualModelImportList.size());
342         Stream.concat(childModelImportList.stream(), parentModelImportList.stream())
343             .forEach(toscaImportByModel -> assertTrue(actualModelImportList.contains(toscaImportByModel)));
344     }
345
346     @Test
347     void addTypesToDefaultImportsTest_nonExistingAdditionalTypesImport() throws IOException {
348         var modelName = "model";
349         final Path testResourcePath = Path.of("src/test/resources/modelOperation");
350
351         final var dataTypesPath = testResourcePath.resolve(Path.of("input-data_types.yaml"));
352         final var dataTypes = Files.readString(dataTypesPath);
353
354         final Path import1RelativePath = Path.of("original-import-1.yaml");
355         final Path import1Path = testResourcePath.resolve(import1RelativePath);
356         final Path import2RelativePath = Path.of("original-import-2.yaml");
357         final Path import2Path = testResourcePath.resolve(import2RelativePath);
358
359         var toscaImportByModel1 = new ToscaImportByModel();
360         toscaImportByModel1.setModelId(modelName);
361         toscaImportByModel1.setFullPath(import1RelativePath.toString());
362         toscaImportByModel1.setContent(Files.readString(import1Path));
363
364         var toscaImportByModel2 = new ToscaImportByModel();
365         toscaImportByModel2.setModelId(modelName);
366         toscaImportByModel2.setFullPath(import2RelativePath.toString());
367         toscaImportByModel2.setContent(Files.readString(import2Path));
368
369         final List<ToscaImportByModel> modelImports = new ArrayList<>();
370         modelImports.add(toscaImportByModel1);
371         modelImports.add(toscaImportByModel2);
372         when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
373
374         modelOperation.addTypesToDefaultImports(ElementTypeEnum.DATA_TYPE, dataTypes, modelName);
375         ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
376         verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
377
378         final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
379         assertEquals(3, actualImportList.size());
380         assertTrue(actualImportList.contains(toscaImportByModel1));
381         assertTrue(actualImportList.contains(toscaImportByModel2));
382
383         var expectedAdditionalTypesImport = new ToscaImportByModel();
384         expectedAdditionalTypesImport.setModelId(modelName);
385         expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
386         expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-1.yaml"))));
387         final ToscaImportByModel actualAdditionalTypesImport =
388             actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
389         assertNotNull(actualAdditionalTypesImport);
390         assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
391
392         var expectedImport1 = new ToscaImportByModel();
393         expectedImport1.setModelId(modelName);
394         expectedImport1.setFullPath(import1RelativePath.toString());
395         expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-1.yaml"))));
396         final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
397         assertNotNull(actualImport1);
398         assertEquals(expectedImport1.getContent(), actualImport1.getContent());
399
400         var expectedImport2 = new ToscaImportByModel();
401         expectedImport2.setModelId(modelName);
402         expectedImport2.setFullPath(import2RelativePath.toString());
403         expectedImport2.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-2.yaml"))));
404         final ToscaImportByModel actualImport2 = actualImportList.stream().filter(expectedImport2::equals).findFirst().orElse(null);
405         assertNotNull(actualImport2);
406         assertEquals(expectedImport2.getContent(), actualImport2.getContent());
407     }
408
409     @Test
410     void addArtifactsToDefaultImportsTest_nonExistingAdditionalTypesImport() throws IOException {
411         var modelName = "model";
412         final Path testResourcePath = Path.of("src/test/resources/modelOperation");
413
414         final var dataTypesPath = testResourcePath.resolve(Path.of("input-artifact_types.yaml"));
415         final var dataTypes = Files.readString(dataTypesPath);
416
417         final Path import1RelativePath = Path.of("original-import-3.yaml");
418         final Path import1Path = testResourcePath.resolve(import1RelativePath);
419
420         var toscaImportByModel1 = new ToscaImportByModel();
421         toscaImportByModel1.setModelId(modelName);
422         toscaImportByModel1.setFullPath(import1RelativePath.toString());
423         toscaImportByModel1.setContent(Files.readString(import1Path));
424
425         final List<ToscaImportByModel> modelImports = new ArrayList<>();
426         modelImports.add(toscaImportByModel1);
427         when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
428
429         modelOperation.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, dataTypes, modelName);
430         ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
431         verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
432
433         final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
434         assertEquals(2, actualImportList.size());
435         assertTrue(actualImportList.contains(toscaImportByModel1));
436
437         var expectedAdditionalTypesImport = new ToscaImportByModel();
438         expectedAdditionalTypesImport.setModelId(modelName);
439         expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
440         expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-3.yaml"))));
441         final ToscaImportByModel actualAdditionalTypesImport =
442             actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
443         assertNotNull(actualAdditionalTypesImport);
444         assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
445
446         var expectedImport1 = new ToscaImportByModel();
447         expectedImport1.setModelId(modelName);
448         expectedImport1.setFullPath(import1RelativePath.toString());
449         expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-3.yaml"))));
450         final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
451         assertNotNull(actualImport1);
452         assertEquals(expectedImport1.getContent(), actualImport1.getContent());
453
454     }
455
456     @Test
457     void addTypesToDefaultImportsTest_existingAdditionalTypesImport() throws IOException {
458         var modelName = "model";
459         final Path testResourcePath = Path.of("src/test/resources/modelOperation");
460
461         final var dataTypesPath = testResourcePath.resolve(Path.of("input-data_types.yaml"));
462         final var dataTypes = Files.readString(dataTypesPath);
463
464         final Path import1RelativePath = Path.of("original-import-1.yaml");
465         final Path import1Path = testResourcePath.resolve(import1RelativePath);
466
467         var toscaImportByModel1 = new ToscaImportByModel();
468         toscaImportByModel1.setModelId(modelName);
469         toscaImportByModel1.setFullPath(import1RelativePath.toString());
470         toscaImportByModel1.setContent(Files.readString(import1Path));
471
472         var originalAdditionalTypesImport = new ToscaImportByModel();
473         originalAdditionalTypesImport.setModelId(modelName);
474         originalAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
475         final Path originalAdditionalTypesImportPath = testResourcePath.resolve(Path.of("original-additional_types-1.yaml"));
476         originalAdditionalTypesImport.setContent(Files.readString(originalAdditionalTypesImportPath));
477
478         final List<ToscaImportByModel> modelImports = new ArrayList<>();
479         modelImports.add(toscaImportByModel1);
480         modelImports.add(originalAdditionalTypesImport);
481         when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
482
483         modelOperation.addTypesToDefaultImports(ElementTypeEnum.DATA_TYPE, dataTypes, modelName);
484         ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
485         verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
486
487         final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
488         assertEquals(2, actualImportList.size());
489         assertTrue(actualImportList.contains(toscaImportByModel1));
490
491         var expectedAdditionalTypesImport = new ToscaImportByModel();
492         expectedAdditionalTypesImport.setModelId(modelName);
493         expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
494         expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-2.yaml"))));
495         final ToscaImportByModel actualAdditionalTypesImport =
496             actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
497         assertNotNull(actualAdditionalTypesImport);
498         assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
499
500         var expectedImport1 = new ToscaImportByModel();
501         expectedImport1.setModelId(modelName);
502         expectedImport1.setFullPath(import1RelativePath.toString());
503         expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-1.yaml"))));
504         final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
505         assertNotNull(actualImport1);
506         assertEquals(expectedImport1.getContent(), actualImport1.getContent());
507         
508         // Update the added additional type
509         final var updatedDataTypesPath = testResourcePath.resolve(Path.of("input-data_types-updated.yaml"));
510         final var updatedDataTypes = Files.readString(updatedDataTypesPath);
511         modelOperation.updateTypesInAdditionalTypesImport(ElementTypeEnum.DATA_TYPE, updatedDataTypes, modelName);
512         
513         ArgumentCaptor<List<ToscaImportByModel>> updatedImportListArgumentCaptor = ArgumentCaptor.forClass(List.class);
514         verify(toscaModelImportCassandraDao, times(2)).saveAll(eq(modelName), updatedImportListArgumentCaptor.capture());
515
516         final List<ToscaImportByModel> updatedActualImportList = updatedImportListArgumentCaptor.getValue();
517         assertEquals(2, updatedActualImportList.size());
518         
519         var expectedUpdatedAdditionalTypesImport = new ToscaImportByModel();
520         expectedUpdatedAdditionalTypesImport.setModelId(modelName);
521         expectedUpdatedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
522         expectedUpdatedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-2-updated.yaml"))));
523         final ToscaImportByModel actualUpdatedAdditionalTypesImport =
524             actualImportList.stream().filter(expectedUpdatedAdditionalTypesImport::equals).findFirst().orElse(null);
525         assertNotNull(actualUpdatedAdditionalTypesImport);
526         
527         assertTrue(actualUpdatedAdditionalTypesImport.getContent().contains("added_property_1"));
528         assertTrue(actualUpdatedAdditionalTypesImport.getContent().contains("added_property_2"));
529     }
530
531     @Test
532     void addArtifactsToDefaultImportsTest_existingAdditionalTypesImport() throws IOException {
533         var modelName = "model";
534         final Path testResourcePath = Path.of("src/test/resources/modelOperation");
535
536         final var dataTypesPath = testResourcePath.resolve(Path.of("input-artifact_types.yaml"));
537         final var dataTypes = Files.readString(dataTypesPath);
538
539         final Path import1RelativePath = Path.of("original-import-3.yaml");
540         final Path import1Path = testResourcePath.resolve(import1RelativePath);
541
542         var toscaImportByModel1 = new ToscaImportByModel();
543         toscaImportByModel1.setModelId(modelName);
544         toscaImportByModel1.setFullPath(import1RelativePath.toString());
545         toscaImportByModel1.setContent(Files.readString(import1Path));
546
547         var originalAdditionalTypesImport = new ToscaImportByModel();
548         originalAdditionalTypesImport.setModelId(modelName);
549         originalAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
550         final Path originalAdditionalTypesImportPath = testResourcePath.resolve(Path.of("original-additional_types-2.yaml"));
551         originalAdditionalTypesImport.setContent(Files.readString(originalAdditionalTypesImportPath));
552
553         final List<ToscaImportByModel> modelImports = new ArrayList<>();
554         modelImports.add(toscaImportByModel1);
555         modelImports.add(originalAdditionalTypesImport);
556         when(toscaModelImportCassandraDao.findAllByModel(modelName)).thenReturn(modelImports);
557
558         modelOperation.addTypesToDefaultImports(ElementTypeEnum.ARTIFACT_TYPE, dataTypes, modelName);
559         ArgumentCaptor<List<ToscaImportByModel>> importListArgumentCaptor = ArgumentCaptor.forClass(List.class);
560         verify(toscaModelImportCassandraDao).saveAll(eq(modelName), importListArgumentCaptor.capture());
561
562         final List<ToscaImportByModel> actualImportList = importListArgumentCaptor.getValue();
563         assertEquals(2, actualImportList.size());
564         assertTrue(actualImportList.contains(toscaImportByModel1));
565
566         var expectedAdditionalTypesImport = new ToscaImportByModel();
567         expectedAdditionalTypesImport.setModelId(modelName);
568         expectedAdditionalTypesImport.setFullPath(ADDITIONAL_TYPE_DEFINITIONS_PATH.toString());
569         expectedAdditionalTypesImport.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-additional_types-3.yaml"))));
570         final ToscaImportByModel actualAdditionalTypesImport =
571             actualImportList.stream().filter(expectedAdditionalTypesImport::equals).findFirst().orElse(null);
572         assertNotNull(actualAdditionalTypesImport);
573         assertEquals(expectedAdditionalTypesImport.getContent(), actualAdditionalTypesImport.getContent());
574
575         var expectedImport1 = new ToscaImportByModel();
576         expectedImport1.setModelId(modelName);
577         expectedImport1.setFullPath(import1RelativePath.toString());
578         expectedImport1.setContent(Files.readString(testResourcePath.resolve(Path.of("expected-import-3.yaml"))));
579         final ToscaImportByModel actualImport1 = actualImportList.stream().filter(expectedImport1::equals).findFirst().orElse(null);
580         assertNotNull(actualImport1);
581         assertEquals(expectedImport1.getContent(), actualImport1.getContent());
582
583     }
584
585     private ToscaImportByModel createModelImport(final String parentModelName, final String importPath) {
586         var toscaImportByModel = new ToscaImportByModel();
587         toscaImportByModel.setModelId(parentModelName);
588         toscaImportByModel.setFullPath(importPath);
589         return toscaImportByModel;
590     }
591 }