2 * ============LICENSE_START=======================================================
3 * Copyright (C) 2024 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
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 * SPDX-License-Identifier: Apache-2.0
18 * ============LICENSE_END=========================================================
21 package org.onap.cps.policyexecutor.stub.controller
23 import com.fasterxml.jackson.databind.ObjectMapper
24 import org.onap.cps.policyexecutor.stub.model.NcmpDelete
25 import org.onap.cps.policyexecutor.stub.model.PolicyExecutionRequest
26 import org.onap.cps.policyexecutor.stub.model.PolicyExecutionResponse
27 import org.onap.cps.policyexecutor.stub.model.Request
28 import org.springframework.beans.factory.annotation.Autowired
29 import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest
30 import org.springframework.http.HttpStatus
31 import org.springframework.http.MediaType
32 import org.springframework.test.web.servlet.MockMvc
33 import spock.lang.Specification
35 import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post
37 @WebMvcTest(PolicyExecutorStubController)
38 class PolicyExecutorStubControllerSpec extends Specification {
44 ObjectMapper objectMapper
46 def url = '/policy-executor/api/v1/some-action'
48 def 'Execute policy action.'() {
49 given: 'a policy execution request with target: #targetIdentifier'
50 def requestBody = createRequestBody(targetIdentifier)
51 when: 'request is posted'
52 def response = mockMvc.perform(post(url)
53 .header('Authorization','some string')
54 .contentType(MediaType.APPLICATION_JSON)
55 .content(requestBody))
57 then: 'response status is Ok'
58 assert response.status == HttpStatus.OK.value()
59 and: 'the response body has the expected decision details'
60 def responseBody = response.contentAsString
61 def policyExecutionResponse = objectMapper.readValue(responseBody, PolicyExecutionResponse.class)
62 assert policyExecutionResponse.decisionId == expectedDecsisonId
63 assert policyExecutionResponse.decision == expectedDecision
64 assert policyExecutionResponse.message == expectedMessage
65 where: 'the following targets are used'
66 targetIdentifier || expectedDecsisonId | expectedDecision | expectedMessage
67 'some fdn' || '1' | 'deny' | "Only FDNs containing 'cps-is-great' are allowed"
68 'fdn with cps-is-great' || '2' | 'allow' | 'All good'
71 def 'Execute policy action with a HTTP error code.'() {
72 given: 'a policy execution request with a target fdn with a 3-digit error code'
73 def requestBody = createRequestBody('target with error code 418')
74 when: 'request is posted'
75 def response = mockMvc.perform(post(url)
76 .header('Authorization','some string')
77 .contentType(MediaType.APPLICATION_JSON)
78 .content(requestBody))
80 then: 'response status the same error code as in target fdn'
81 assert response.status == 418
84 def 'Execute policy action without authorization header.'() {
85 given: 'a valid policy execution request'
86 def requestBody = createRequestBody('some target')
87 when: 'request is posted without authorization header'
88 def response = mockMvc.perform(post(url)
89 .contentType(MediaType.APPLICATION_JSON)
90 .content(requestBody))
92 then: 'response status is OK'
93 assert response.status == HttpStatus.OK.value()
96 def 'Execute policy action with no requests.'() {
97 given: 'a policy execution request'
98 def policyExecutionRequest = new PolicyExecutionRequest('some decision type', [])
99 def requestBody = objectMapper.writeValueAsString(policyExecutionRequest)
100 when: 'request is posted'
101 def response = mockMvc.perform(post(url)
102 .header('Authorization','some string')
103 .contentType(MediaType.APPLICATION_JSON)
104 .content(requestBody))
105 .andReturn().response
106 then: 'response status is Bad Request'
107 assert response.status == HttpStatus.BAD_REQUEST.value()
110 def 'Execute policy action with invalid json for request data.'() {
111 given: 'a policy execution request'
112 def request = new Request('ncmp-delete-schema:1.0.0', 'invalid json')
113 def policyExecutionRequest = new PolicyExecutionRequest('some decision type', [request])
114 def requestBody = objectMapper.writeValueAsString(policyExecutionRequest)
115 when: 'request is posted'
116 def response = mockMvc.perform(post(url)
117 .header('Authorization','some string')
118 .contentType(MediaType.APPLICATION_JSON)
119 .content(requestBody))
120 .andReturn().response
121 then: 'response status is Bad Request'
122 assert response.status == HttpStatus.BAD_REQUEST.value()
125 def 'Execute policy action with missing or invalid attributes.'() {
126 given: 'a policy execution request with decisionType=#decisionType, schema=#schema, targetIdentifier=#targetIdentifier'
127 def requestBody = createRequestBody(decisionType, schema, targetIdentifier)
128 when: 'request is posted'
129 def response = mockMvc.perform(post(url)
130 .header('Authorization','something')
131 .contentType(MediaType.APPLICATION_JSON)
132 .content(requestBody))
133 .andReturn().response
134 then: 'response status as expected'
135 assert response.status == expectedStatus.value()
136 where: 'following parameters are used'
137 decisionType | schema | targetIdentifier || expectedStatus
138 'something' | 'ncmp-delete-schema:1.0.0' | 'something' || HttpStatus.OK
139 null | 'ncmp-delete-schema:1.0.0' | 'something' || HttpStatus.BAD_REQUEST
140 'something' | 'other schema' | 'something' || HttpStatus.BAD_REQUEST
141 'something' | 'ncmp-delete-schema:1.0.0' | null || HttpStatus.BAD_REQUEST
144 def createRequestBody(decisionType, schema, targetIdentifier) {
145 def ncmpDelete = new NcmpDelete(targetIdentifier: targetIdentifier)
146 def request = new Request(schema, objectMapper.writeValueAsString(ncmpDelete))
147 def policyExecutionRequest = new PolicyExecutionRequest(decisionType, [request])
148 return objectMapper.writeValueAsString(policyExecutionRequest)
151 def createRequestBody(targetIdentifier) {
152 return createRequestBody('some decision type', 'ncmp-delete-schema:1.0.0', targetIdentifier)