2 // ========================LICENSE_START=================================
5 // Copyright (C) 2022: Nordix Foundation
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===================================
35 "github.com/deepmap/oapi-codegen/pkg/middleware"
36 "github.com/deepmap/oapi-codegen/pkg/testutil"
37 "github.com/labstack/echo/v4"
38 echomiddleware "github.com/labstack/echo/v4/middleware"
39 "github.com/stretchr/testify/assert"
40 "oransc.org/nonrtric/capifcore/internal/common29122"
41 "oransc.org/nonrtric/capifcore/internal/eventsapi"
42 "oransc.org/nonrtric/capifcore/internal/restclient"
45 func TestRegisterSubscriptions(t *testing.T) {
46 subscription1 := eventsapi.EventSubscription{
47 Events: []eventsapi.CAPIFEvent{
48 eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
50 NotificationDestination: common29122.Uri("notificationUrl"),
52 serviceUnderTest, requestHandler := getEcho(nil)
53 subscriberId := "subscriberId"
55 result := testutil.NewRequest().Post("/"+subscriberId+"/subscriptions").WithJsonBody(subscription1).Go(t, requestHandler)
56 assert.Equal(t, http.StatusCreated, result.Code())
57 var resultEvent eventsapi.EventSubscription
58 err := result.UnmarshalBodyToObject(&resultEvent)
59 assert.NoError(t, err, "error unmarshaling response")
60 assert.Equal(t, resultEvent, subscription1)
61 assert.Regexp(t, "http://example.com/"+subscriberId+"/subscriptions/"+subscriberId+"[0-9]+", result.Recorder.Header().Get(echo.HeaderLocation))
62 subscriptionId1 := path.Base(result.Recorder.Header().Get(echo.HeaderLocation))
64 subscription2 := subscription1
65 subscription2.Events = []eventsapi.CAPIFEvent{
66 eventsapi.CAPIFEventAPIINVOKERUPDATED,
68 result = testutil.NewRequest().Post("/"+subscriberId+"/subscriptions").WithJsonBody(subscription2).Go(t, requestHandler)
69 assert.Regexp(t, "http://example.com/"+subscriberId+"/subscriptions/"+subscriberId+"[0-9]+", result.Recorder.Header().Get(echo.HeaderLocation))
70 subscriptionId2 := path.Base(result.Recorder.Header().Get(echo.HeaderLocation))
72 assert.NotEqual(t, subscriptionId1, subscriptionId2)
73 registeredSub1 := serviceUnderTest.getSubscription(subscriptionId1)
74 assert.Equal(t, subscription1, *registeredSub1)
75 registeredSub2 := serviceUnderTest.getSubscription(subscriptionId2)
76 assert.Equal(t, subscription2, *registeredSub2)
79 func TestDeregisterSubscription(t *testing.T) {
80 subscription := eventsapi.EventSubscription{
81 Events: []eventsapi.CAPIFEvent{
82 eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
84 NotificationDestination: common29122.Uri(""),
86 serviceUnderTest, requestHandler := getEcho(nil)
88 serviceUnderTest.addSubscription(subId, subscription)
90 result := testutil.NewRequest().Delete("/subscriberId/subscriptions/"+subId).Go(t, requestHandler)
91 assert.Equal(t, http.StatusNoContent, result.Code())
92 assert.Nil(t, serviceUnderTest.getSubscription(subId))
95 func TestSendEvent(t *testing.T) {
96 notificationUrl := "url"
97 apiIds := []string{"apiId"}
99 newEvent := eventsapi.EventNotification{
100 EventDetail: &eventsapi.CAPIFEventDetail{
103 Events: eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
105 wg := sync.WaitGroup{}
106 clientMock := NewTestClient(func(req *http.Request) *http.Response {
107 if req.URL.String() == notificationUrl {
108 assert.Equal(t, req.Method, "PUT")
109 assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
110 newEvent.SubscriptionId = subId
111 assert.Equal(t, newEvent, getBodyAsEvent(req, t))
113 return &http.Response{
115 Body: ioutil.NopCloser(bytes.NewBufferString(`OK`)),
116 Header: make(http.Header), // Must be set to non-nil value or it panics
119 t.Error("Wrong call to client: ", req)
123 serviceUnderTest, _ := getEcho(clientMock)
125 serviceUnderTest.addSubscription(subId, eventsapi.EventSubscription{
126 Events: []eventsapi.CAPIFEvent{
127 eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
129 NotificationDestination: common29122.Uri(notificationUrl),
131 sub2 := eventsapi.EventSubscription{
132 Events: []eventsapi.CAPIFEvent{
133 eventsapi.CAPIFEventACCESSCONTROLPOLICYUNAVAILABLE,
135 NotificationDestination: common29122.Uri(notificationUrl),
137 serviceUnderTest.addSubscription("other", sub2)
141 serviceUnderTest.GetNotificationChannel() <- newEvent
144 if waitTimeout(&wg, 1*time.Second) {
145 t.Error("Not all calls to server were made")
150 func TestMatchEventType(t *testing.T) {
151 notificationUrl := "url"
153 serviceUnderTest := NewEventService(nil)
154 serviceUnderTest.addSubscription(subId, eventsapi.EventSubscription{
155 Events: []eventsapi.CAPIFEvent{
156 eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
158 NotificationDestination: common29122.Uri(notificationUrl),
159 EventFilters: &[]eventsapi.CAPIFEventFilter{},
161 serviceUnderTest.addSubscription("other", eventsapi.EventSubscription{
162 Events: []eventsapi.CAPIFEvent{
163 eventsapi.CAPIFEventACCESSCONTROLPOLICYUNAVAILABLE,
165 NotificationDestination: common29122.Uri(notificationUrl),
168 event := eventsapi.EventNotification{
169 SubscriptionId: subId,
170 Events: eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
173 matchingSubs := serviceUnderTest.getMatchingSubs(event)
174 assert.Len(t, matchingSubs, 1)
175 assert.Equal(t, subId, matchingSubs[0])
178 func TestMatchesApiIds(t *testing.T) {
180 apiIds := []string{apiId, "otherApiId"}
181 eventFilters := []eventsapi.CAPIFEventFilter{
188 eventApiIds := []string{apiId}
189 assert.True(t, matchesApiIds(eventApiIds, eventFilters))
190 assert.True(t, matchesApiIds(nil, eventFilters))
192 altApiIds := []string{"anotherApiId"}
193 unMatchingFilterAdded := append(eventFilters, eventsapi.CAPIFEventFilter{
196 assert.False(t, matchesApiIds(eventApiIds, unMatchingFilterAdded))
198 apiIds[0] = "anotherId"
199 assert.False(t, matchesApiIds(eventApiIds, eventFilters))
202 func getEcho(client restclient.HTTPClient) (*EventService, *echo.Echo) {
203 swagger, err := eventsapi.GetSwagger()
205 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
209 swagger.Servers = nil
211 es := NewEventService(client)
214 e.Use(echomiddleware.Logger())
215 e.Use(middleware.OapiRequestValidator(swagger))
217 eventsapi.RegisterHandlers(e, es)
221 type RoundTripFunc func(req *http.Request) *http.Response
223 func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
227 // NewTestClient returns *http.Client with Transport replaced to avoid making real calls
228 func NewTestClient(fn RoundTripFunc) *http.Client {
230 Transport: RoundTripFunc(fn),
234 // waitTimeout waits for the waitgroup for the specified max timeout.
235 // Returns true if waiting timed out.
236 func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
237 c := make(chan struct{})
244 return false // completed normally
245 case <-time.After(timeout):
246 return true // timed out
250 func getBodyAsEvent(req *http.Request, t *testing.T) eventsapi.EventNotification {
251 buf := new(bytes.Buffer)
252 if _, err := buf.ReadFrom(req.Body); err != nil {
255 var event eventsapi.EventNotification
256 err := json.Unmarshal(buf.Bytes(), &event)