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 SubscriptionId: subId,
101 EventDetail: &eventsapi.CAPIFEventDetail{
104 Events: eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
106 wg := sync.WaitGroup{}
107 clientMock := NewTestClient(func(req *http.Request) *http.Response {
108 if req.URL.String() == notificationUrl {
109 assert.Equal(t, req.Method, "PUT")
110 assert.Equal(t, "application/json", req.Header.Get("Content-Type"))
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 subscription := eventsapi.EventSubscription{
126 Events: []eventsapi.CAPIFEvent{
127 eventsapi.CAPIFEventSERVICEAPIAVAILABLE,
129 NotificationDestination: common29122.Uri(notificationUrl),
131 serviceUnderTest.addSubscription(subId, subscription)
135 serviceUnderTest.GetNotificationChannel() <- newEvent
138 if waitTimeout(&wg, 1*time.Second) {
139 t.Error("Not all calls to server were made")
145 func getEcho(client restclient.HTTPClient) (*EventService, *echo.Echo) {
146 swagger, err := eventsapi.GetSwagger()
148 fmt.Fprintf(os.Stderr, "Error loading swagger spec\n: %s", err)
152 swagger.Servers = nil
154 es := NewEventService(client)
157 e.Use(echomiddleware.Logger())
158 e.Use(middleware.OapiRequestValidator(swagger))
160 eventsapi.RegisterHandlers(e, es)
164 type RoundTripFunc func(req *http.Request) *http.Response
166 func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
170 // NewTestClient returns *http.Client with Transport replaced to avoid making real calls
171 func NewTestClient(fn RoundTripFunc) *http.Client {
173 Transport: RoundTripFunc(fn),
177 // waitTimeout waits for the waitgroup for the specified max timeout.
178 // Returns true if waiting timed out.
179 func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
180 c := make(chan struct{})
187 return false // completed normally
188 case <-time.After(timeout):
189 return true // timed out
193 func getBodyAsEvent(req *http.Request, t *testing.T) eventsapi.EventNotification {
194 buf := new(bytes.Buffer)
195 if _, err := buf.ReadFrom(req.Body); err != nil {
198 var event eventsapi.EventNotification
199 err := json.Unmarshal(buf.Bytes(), &event)