Type validation in publish service
[nonrtric/plt/sme.git] / capifcore / internal / providermanagement / providermanagement_test.go
1 // -
2 //   ========================LICENSE_START=================================
3 //   O-RAN-SC
4 //   %%
5 //   Copyright (C) 2022: Nordix Foundation
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
10 //
11 //        http://www.apache.org/licenses/LICENSE-2.0
12 //
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===================================
19 //
20
21 package providermanagement
22
23 import (
24         "fmt"
25         "net/http"
26         "os"
27         "testing"
28
29         "github.com/labstack/echo/v4"
30
31         "oransc.org/nonrtric/capifcore/internal/common29122"
32         provapi "oransc.org/nonrtric/capifcore/internal/providermanagementapi"
33
34         "github.com/deepmap/oapi-codegen/pkg/middleware"
35         "github.com/deepmap/oapi-codegen/pkg/testutil"
36         echomiddleware "github.com/labstack/echo/v4/middleware"
37         "github.com/stretchr/testify/assert"
38 )
39
40 var (
41         domainID      = "domain_id_rApp_domain"
42         otherDomainID = "domain_id_other_domain"
43         domainInfo    = "rApp domain"
44         funcInfoAPF   = "rApp as APF"
45         funcIdAPF     = "APF_id_rApp_as_APF"
46         funcInfoAMF   = "rApp as AMF"
47         funcIdAMF     = "AMF_id_rApp_as_AMF"
48         funcInfoAEF   = "rApp as AEF"
49         funcIdAEF     = "AEF_id_rApp_as_AEF"
50 )
51
52 func TestRegisterValidProvider(t *testing.T) {
53         managerUnderTest, requestHandler := getEcho()
54
55         newProvider := getProvider()
56
57         // Register a valid provider
58         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
59
60         assert.Equal(t, http.StatusCreated, result.Code())
61         var resultProvider provapi.APIProviderEnrolmentDetails
62         err := result.UnmarshalBodyToObject(&resultProvider)
63         assert.NoError(t, err, "error unmarshaling response")
64         assert.Equal(t, *resultProvider.ApiProvDomId, domainID)
65         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncId, funcIdAPF)
66         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[1].ApiProvFuncId, funcIdAMF)
67         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[2].ApiProvFuncId, funcIdAEF)
68         assert.Empty(t, resultProvider.FailReason)
69         assert.Equal(t, "http://example.com/registrations/"+*resultProvider.ApiProvDomId, result.Recorder.Header().Get(echo.HeaderLocation))
70         assert.True(t, managerUnderTest.IsFunctionRegistered("APF_id_rApp_as_APF"))
71 }
72
73 func TestUpdateValidProviderWithNewFunction(t *testing.T) {
74         managerUnderTest, requestHandler := getEcho()
75
76         provider := getProvider()
77         provider.ApiProvDomId = &domainID
78         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
79         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
80         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
81         managerUnderTest.registeredProviders[domainID] = provider
82
83         // Modify the provider
84         updatedProvider := getProvider()
85         updatedProvider.ApiProvDomId = &domainID
86         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
87         (*updatedProvider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
88         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
89         newDomainInfo := "New domain info"
90         updatedProvider.ApiProvDomInfo = &newDomainInfo
91         newFunctionInfo := "New function info"
92         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
93         newFuncInfoAEF := "new func as AEF"
94         testFuncs := *updatedProvider.ApiProvFuncs
95         testFuncs = append(testFuncs, provapi.APIProviderFunctionDetails{
96                 ApiProvFuncInfo: &newFuncInfoAEF,
97                 ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
98                 RegInfo: provapi.RegistrationInformation{
99                         ApiProvPubKey: "key",
100                 },
101         })
102         updatedProvider.ApiProvFuncs = &testFuncs
103
104         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
105
106         var resultProvider provapi.APIProviderEnrolmentDetails
107         assert.Equal(t, http.StatusOK, result.Code())
108         err := result.UnmarshalBodyToObject(&resultProvider)
109         assert.NoError(t, err, "error unmarshaling response")
110         assert.Equal(t, newDomainInfo, *resultProvider.ApiProvDomInfo)
111         assert.Equal(t, newFunctionInfo, *(*resultProvider.ApiProvFuncs)[0].ApiProvFuncInfo)
112         assert.Equal(t, *(*resultProvider.ApiProvFuncs)[3].ApiProvFuncId, "AEF_id_new_func_as_AEF")
113         assert.Empty(t, resultProvider.FailReason)
114         assert.True(t, managerUnderTest.IsFunctionRegistered("AEF_id_new_func_as_AEF"))
115 }
116
117 func TestUpdateValidProviderWithDeletedFunction(t *testing.T) {
118         managerUnderTest, requestHandler := getEcho()
119
120         provider := getProvider()
121         provider.ApiProvDomId = &domainID
122         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
123         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
124         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
125         managerUnderTest.registeredProviders[domainID] = provider
126
127         // Modify the provider
128         updatedProvider := getProvider()
129         updatedProvider.ApiProvDomId = &domainID
130         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
131         (*updatedProvider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
132         testFuncs := []provapi.APIProviderFunctionDetails{
133                 (*updatedProvider.ApiProvFuncs)[0],
134                 (*updatedProvider.ApiProvFuncs)[2],
135         }
136         updatedProvider.ApiProvFuncs = &testFuncs
137
138         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
139
140         var resultProvider provapi.APIProviderEnrolmentDetails
141         assert.Equal(t, http.StatusOK, result.Code())
142         err := result.UnmarshalBodyToObject(&resultProvider)
143         assert.NoError(t, err, "error unmarshaling response")
144         assert.Len(t, (*resultProvider.ApiProvFuncs), 2)
145         assert.Empty(t, resultProvider.FailReason)
146         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAMF))
147 }
148
149 func TestUpdateMissingFunction(t *testing.T) {
150         managerUnderTest, requestHandler := getEcho()
151
152         provider := getProvider()
153         provider.ApiProvDomId = &domainID
154         otherId := "otherId"
155         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &otherId
156         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
157         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
158         managerUnderTest.registeredProviders[domainID] = provider
159
160         // Modify the provider
161         updatedProvider := getProvider()
162         updatedProvider.ApiProvDomId = &domainID
163         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
164         newFunctionInfo := "New function info"
165         (*updatedProvider.ApiProvFuncs)[0].ApiProvFuncInfo = &newFunctionInfo
166
167         result := testutil.NewRequest().Put("/registrations/"+domainID).WithJsonBody(updatedProvider).Go(t, requestHandler)
168
169         var errorObj common29122.ProblemDetails
170         assert.Equal(t, http.StatusBadRequest, result.Code())
171         err := result.UnmarshalBodyToObject(&errorObj)
172         assert.NoError(t, err, "error unmarshaling response")
173         assert.Contains(t, *errorObj.Cause, funcIdAPF)
174         assert.Contains(t, *errorObj.Cause, "not registered")
175 }
176
177 func TestDeleteProvider(t *testing.T) {
178         managerUnderTest, requestHandler := getEcho()
179
180         provider := getProvider()
181         provider.ApiProvDomId = &domainID
182         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
183         managerUnderTest.registeredProviders[domainID] = provider
184         assert.True(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
185
186         result := testutil.NewRequest().Delete("/registrations/"+domainID).Go(t, requestHandler)
187
188         assert.Equal(t, http.StatusNoContent, result.Code())
189         assert.False(t, managerUnderTest.IsFunctionRegistered(funcIdAPF))
190 }
191 func TestProviderHandlingValidation(t *testing.T) {
192         _, requestHandler := getEcho()
193
194         newProvider := provapi.APIProviderEnrolmentDetails{}
195
196         // Register an invalid provider
197         result := testutil.NewRequest().Post("/registrations").WithJsonBody(newProvider).Go(t, requestHandler)
198
199         assert.Equal(t, http.StatusBadRequest, result.Code())
200         var problemDetails common29122.ProblemDetails
201         err := result.UnmarshalBodyToObject(&problemDetails)
202         assert.NoError(t, err, "error unmarshaling response")
203         badRequest := http.StatusBadRequest
204         assert.Equal(t, &badRequest, problemDetails.Status)
205         assert.Contains(t, *problemDetails.Cause, "Provider not valid")
206         assert.Contains(t, *problemDetails.Cause, "regSec")
207 }
208
209 func TestGetExposedFunctionsForPublishingFunction(t *testing.T) {
210         managerUnderTest := NewProviderManager()
211
212         provider := getProvider()
213         provider.ApiProvDomId = &domainID
214         (*provider.ApiProvFuncs)[0].ApiProvFuncId = &funcIdAPF
215         (*provider.ApiProvFuncs)[1].ApiProvFuncId = &funcIdAMF
216         (*provider.ApiProvFuncs)[2].ApiProvFuncId = &funcIdAEF
217         managerUnderTest.registeredProviders[domainID] = provider
218         managerUnderTest.registeredProviders[otherDomainID] = getOtherProvider()
219
220         exposedFuncs := managerUnderTest.GetAefsForPublisher(funcIdAPF)
221         assert.Equal(t, 1, len(exposedFuncs))
222         assert.Equal(t, funcIdAEF, exposedFuncs[0])
223 }
224
225 func getProvider() provapi.APIProviderEnrolmentDetails {
226         testFuncs := []provapi.APIProviderFunctionDetails{
227                 {
228                         ApiProvFuncInfo: &funcInfoAPF,
229                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
230                         RegInfo: provapi.RegistrationInformation{
231                                 ApiProvPubKey: "key",
232                         },
233                 },
234                 {
235                         ApiProvFuncInfo: &funcInfoAMF,
236                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
237                         RegInfo: provapi.RegistrationInformation{
238                                 ApiProvPubKey: "key",
239                         },
240                 },
241                 {
242                         ApiProvFuncInfo: &funcInfoAEF,
243                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
244                         RegInfo: provapi.RegistrationInformation{
245                                 ApiProvPubKey: "key",
246                         },
247                 },
248         }
249         return provapi.APIProviderEnrolmentDetails{
250                 RegSec:         "sec",
251                 ApiProvDomInfo: &domainInfo,
252                 ApiProvFuncs:   &testFuncs,
253         }
254
255 }
256
257 func getOtherProvider() provapi.APIProviderEnrolmentDetails {
258         otherDomainInfo := "other domain"
259         otherFuncInfoAPF := "other as APF"
260         otherApfId := "APF_id_other_as_APF"
261         otherFuncInfoAMF := "other as AMF"
262         otherAmfId := "AMF_id_other_as_AMF"
263         otherFuncInfoAEF := "other as AEF"
264         otherAefId := "AEF_id_other_as_AEF"
265         testFuncs := []provapi.APIProviderFunctionDetails{
266                 {
267                         ApiProvFuncId:   &otherApfId,
268                         ApiProvFuncInfo: &otherFuncInfoAPF,
269                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAPF,
270                 },
271                 {
272                         ApiProvFuncId:   &otherAmfId,
273                         ApiProvFuncInfo: &otherFuncInfoAMF,
274                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAMF,
275                 },
276                 {
277                         ApiProvFuncId:   &otherAefId,
278                         ApiProvFuncInfo: &otherFuncInfoAEF,
279                         ApiProvFuncRole: provapi.ApiProviderFuncRoleAEF,
280                 },
281         }
282         return provapi.APIProviderEnrolmentDetails{
283                 ApiProvDomId:   &otherDomainID,
284                 ApiProvDomInfo: &otherDomainInfo,
285                 ApiProvFuncs:   &testFuncs,
286         }
287
288 }
289
290 func getEcho() (*ProviderManager, *echo.Echo) {
291         swagger, err := provapi.GetSwagger()
292         if err != nil {
293                 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
294                 os.Exit(1)
295         }
296
297         swagger.Servers = nil
298
299         pm := NewProviderManager()
300
301         e := echo.New()
302         e.Use(echomiddleware.Logger())
303         e.Use(middleware.OapiRequestValidator(swagger))
304
305         provapi.RegisterHandlers(e, pm)
306         return pm, e
307 }