Bump upstreams
[netconf.git] / restconf / restconf-nb / src / test / java / org / opendaylight / restconf / nb / jaxrs / RestconfDataPutTest.java
1 /*
2  * Copyright (c) 2023 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.restconf.nb.jaxrs;
9
10 import static org.junit.jupiter.api.Assertions.assertNull;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.ArgumentMatchers.eq;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.doReturn;
15 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFalseFluentFuture;
16 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateFluentFuture;
17 import static org.opendaylight.yangtools.util.concurrent.FluentFutures.immediateTrueFluentFuture;
18
19 import java.util.List;
20 import java.util.Optional;
21 import javax.ws.rs.core.MultivaluedHashMap;
22 import javax.ws.rs.core.MultivaluedMap;
23 import org.junit.jupiter.api.BeforeEach;
24 import org.junit.jupiter.api.Test;
25 import org.junit.jupiter.api.extension.ExtendWith;
26 import org.mockito.Mock;
27 import org.mockito.junit.jupiter.MockitoExtension;
28 import org.opendaylight.mdsal.common.api.CommitInfo;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.dom.api.DOMActionService;
31 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
32 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadTransaction;
33 import org.opendaylight.mdsal.dom.api.DOMDataTreeReadWriteTransaction;
34 import org.opendaylight.mdsal.dom.api.DOMMountPointService;
35 import org.opendaylight.mdsal.dom.api.DOMRpcService;
36 import org.opendaylight.mdsal.dom.api.DOMSchemaService;
37 import org.opendaylight.mdsal.dom.spi.FixedDOMSchemaService;
38 import org.opendaylight.netconf.dom.api.NetconfDataTreeService;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
40
41 @ExtendWith(MockitoExtension.class)
42 class RestconfDataPutTest extends AbstractRestconfTest {
43     private final MultivaluedMap<String, String> queryParamenters = new MultivaluedHashMap<>();
44
45     @Mock
46     private DOMDataTreeReadTransaction readTx;
47     @Mock
48     private DOMDataTreeReadWriteTransaction rwTx;
49
50     @BeforeEach
51     void beforeEach() {
52         doReturn(readTx).when(dataBroker).newReadOnlyTransaction();
53         doReturn(rwTx).when(dataBroker).newReadWriteTransaction();
54         doReturn(CommitInfo.emptyFluentFuture()).when(rwTx).commit();
55     }
56
57     @Test
58     void testPutData() {
59         doReturn(queryParamenters).when(uriInfo).getQueryParameters();
60         doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
61         doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
62
63         assertNull(assertEntity(204, ar -> restconf.dataJsonPUT(JUKEBOX_API_PATH, uriInfo, stringInputStream("""
64             {
65               "example-jukebox:jukebox" : {
66                 "player": {
67                   "gap": "0.2"
68                 }
69               }
70             }"""), ar)));
71     }
72
73     @Test
74     void testPutDataWithMountPoint() {
75         doReturn(queryParamenters).when(uriInfo).getQueryParameters();
76         doReturn(immediateTrueFluentFuture()).when(readTx).exists(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID);
77         doNothing().when(rwTx).put(LogicalDatastoreType.CONFIGURATION, JUKEBOX_IID, EMPTY_JUKEBOX);
78         doReturn(Optional.of(mountPoint)).when(mountPointService).getMountPoint(any());
79         doReturn(Optional.of(new FixedDOMSchemaService(JUKEBOX_SCHEMA))).when(mountPoint)
80             .getService(DOMSchemaService.class);
81         doReturn(Optional.of(dataBroker)).when(mountPoint).getService(DOMDataBroker.class);
82         doReturn(Optional.of(rpcService)).when(mountPoint).getService(DOMRpcService.class);
83         doReturn(Optional.empty()).when(mountPoint).getService(DOMActionService.class);
84         doReturn(Optional.empty()).when(mountPoint).getService(DOMMountPointService.class);
85         doReturn(Optional.empty()).when(mountPoint).getService(NetconfDataTreeService.class);
86
87         assertNull(assertEntity(204, ar -> restconf.dataXmlPUT(
88             apiPath("example-jukebox:jukebox/yang-ext:mount/example-jukebox:jukebox"), uriInfo,
89             stringInputStream("""
90                 <jukebox xmlns="http://example.com/ns/example-jukebox">
91                   <player>
92                     <gap>0.2</gap>
93                   </player>
94                 </jukebox>"""), ar)));
95     }
96
97     @Test
98     public void testPutDataWithInsertLast() {
99         // Mocking the query parameters to include 'insert=last'
100         final var queryParams = new MultivaluedHashMap<String, String>();
101         queryParams.put("insert", List.of("last"));
102         doReturn(queryParams).when(uriInfo).getQueryParameters();
103
104         doReturn(immediateFalseFluentFuture()).when(readTx)
105             .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
106
107         assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
108             apiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
109             {
110               "example-jukebox:song" : [
111                 {
112                    "index": "3"
113                 }
114               ]
115             }"""), ar)));
116     }
117
118     @Test
119     public void testPutDataWithInsertFirst() {
120         // Mocking the query parameters to include 'insert=first'
121         final var queryParams = new MultivaluedHashMap<String, String>();
122         queryParams.put("insert", List.of("first"));
123         doReturn(queryParams).when(uriInfo).getQueryParameters();
124
125         doReturn(immediateFalseFluentFuture()).when(readTx)
126             .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
127         // Mocking existed playlist with two songs in DS
128         doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
129             .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
130
131         assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
132             apiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
133             {
134               "example-jukebox:song" : [
135                 {
136                    "index": "3"
137                 }
138               ]
139             }"""), ar)));
140     }
141
142     @Test
143     public void testPutDataWithInsertBefore() {
144         // Mocking the query parameters to include 'insert=before' and 'point=example-jukebox:jukebox/playlist=0/song=2'
145         final var queryParams = new MultivaluedHashMap<String, String>();
146         queryParams.put("insert", List.of("before"));
147         queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=2"));
148         doReturn(queryParams).when(uriInfo).getQueryParameters();
149
150         doReturn(immediateFalseFluentFuture()).when(readTx)
151             .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
152         // Mocking existed playlist with two songs in DS
153         doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
154             .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
155
156         assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
157             apiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
158             {
159               "example-jukebox:song" : [
160                 {
161                    "index": "3",
162                    "id" = "C"
163                 }
164               ]
165             }"""), ar)));
166     }
167
168     @Test
169     public void testPutDataWithInsertAfter() {
170         // Mocking the query parameters to include 'insert=after' and 'point=example-jukebox:jukebox/playlist=0/song=1'
171         final var queryParams = new MultivaluedHashMap<String, String>();
172         queryParams.put("insert", List.of("after"));
173         queryParams.put("point", List.of("example-jukebox:jukebox/playlist=0/song=1"));
174         doReturn(queryParams).when(uriInfo).getQueryParameters();
175
176         doReturn(immediateFalseFluentFuture()).when(readTx)
177             .exists(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
178         doReturn(immediateFluentFuture(Optional.of(PLAYLIST_WITH_SONGS))).when(rwTx)
179             .read(eq(LogicalDatastoreType.CONFIGURATION), any(YangInstanceIdentifier.class));
180
181         assertNull(assertEntity(201, ar -> restconf.dataJsonPUT(
182             apiPath("example-jukebox:jukebox/playlist=0/song=3"), uriInfo, stringInputStream("""
183             {
184               "example-jukebox:song" : [
185                 {
186                    "index": "3",
187                    "id" = "C"
188                 }
189               ]
190             }"""), ar)));
191     }
192 }