Add basic security to query interface
[cps/cps-temporal.git] / src / test / groovy / org / onap / cps / temporal / domain / SearchCriteriaSpec.groovy
1 /*
2  * ============LICENSE_START=======================================================
3  * Copyright (c) 2021 Bell Canada.
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
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  * SPDX-License-Identifier: Apache-2.0
18  * ============LICENSE_END=========================================================
19  */
20 package org.onap.cps.temporal.domain
21
22 import org.springframework.data.domain.Sort
23 import spock.lang.Specification
24 import java.time.OffsetDateTime
25
26 class SearchCriteriaSpec extends Specification {
27
28     def myDataspace = 'my-dataspace'
29     def myAnchorName = 'my-anchor'
30     def myschemaSetName = 'my-schemaset'
31
32
33     def 'Search Criteria has default values if not provided.'() {
34         def myPayloadFilter = '{"status": "down"}'
35         when: 'search criteria is created'
36             def searchCriteria = SearchCriteria.builder()
37                 .dataspaceName(myDataspace)
38                 .schemaSetName(myschemaSetName)
39                 .pagination(0, 10)
40                 .simplePayloadFilter(myPayloadFilter)
41                 .build()
42
43         then: 'search criteria has default value for sort'
44             searchCriteria.getPageable().getSort() == Sort.by(Sort.Direction.DESC, 'observed_timestamp')
45         and: 'created before has almost current time as default value'
46             OffsetDateTime.now().minusMinutes(5).isBefore(searchCriteria.getCreatedBefore())
47         and: 'contains the provided value to builder'
48             searchCriteria.getDataspaceName() == myDataspace
49             searchCriteria.getSchemaSetName() == myschemaSetName
50             searchCriteria.getSimplePayloadFilter() == myPayloadFilter
51             searchCriteria.getPageable().getPageNumber() == 0
52             searchCriteria.getPageable().getPageSize() == 10
53
54     }
55
56     def 'Search Criteria with the provided values.'() {
57
58         given: 'sort by parameter'
59             def sortBy = Sort.by(Sort.Direction.DESC, 'observed_timestamp')
60         and: 'data created one day ago'
61             def lastDayAsCreatedBefore = OffsetDateTime.now().minusDays(1)
62         and: 'observed timestamp'
63             def nowAsObservedAfter = OffsetDateTime.now()
64         and: 'simple payload filter'
65             def simplePayloadFilter = '{"message":"hello world"}'
66
67         when: 'search criteria is created'
68             def searchCriteria = SearchCriteria.builder()
69                 .dataspaceName(myDataspace)
70                 .schemaSetName(myschemaSetName)
71                 .anchorName(myAnchorName)
72                 .pagination(0, 10)
73                 .simplePayloadFilter(simplePayloadFilter)
74                 .sort(sortBy)
75                 .observedAfter(nowAsObservedAfter)
76                 .createdBefore(lastDayAsCreatedBefore)
77                 .build()
78
79         then: 'search criteria has expected value'
80             with(searchCriteria) {
81                 dataspaceName == myDataspace
82                 schemaSetName == myschemaSetName
83                 anchorName == myAnchorName
84                 observedAfter == nowAsObservedAfter
85                 createdBefore == lastDayAsCreatedBefore
86                 it.simplePayloadFilter == simplePayloadFilter
87                 pageable.getPageNumber() == 0
88                 pageable.getPageSize() == 10
89                 pageable.getSort() == sortBy
90             }
91     }
92
93     def 'Error handling: missing dataspace.'() {
94         when: 'search criteria is created without dataspace'
95             SearchCriteria.builder()
96                 .anchorName(myAnchorName)
97                 .pagination(0, 10)
98                 .build()
99         then: 'exception is thrown'
100             thrown(IllegalStateException)
101     }
102
103     def 'Error handling: missing both schemaset and anchor.'() {
104         when: 'search criteria is created without schemaset and anchor'
105             SearchCriteria.builder()
106                 .dataspaceName(myDataspace)
107                 .pagination(0, 10)
108                 .build()
109         then: 'exception is thrown'
110             thrown(IllegalStateException)
111     }
112
113     def 'Error handling: missing pagination.'() {
114         when: 'search criteria is created without pagination'
115             SearchCriteria.builder()
116                 .dataspaceName(myDataspace)
117                 .anchorName(myAnchorName)
118                 .build()
119         then: 'exception is thrown'
120             thrown(IllegalStateException)
121     }
122
123     def 'Error Handling: sort based on #scenario .'() {
124         when: 'search criteria is created without sorting information'
125             SearchCriteria.builder()
126                 .dataspaceName(myDataspace)
127                 .anchorName(myAnchorName)
128                 .pagination(0, 1)
129                 .sort(sort)
130                 .build()
131         then: 'exception is thrown'
132             def illegalArgumentException = thrown(IllegalArgumentException)
133             def message = illegalArgumentException.getMessage();
134             assert message.contains('sort')
135             assert message.contains(expectedExceptionMessage)
136         where:
137             scenario                 | sort                                       | expectedExceptionMessage
138             'null'                   | null                                       | 'null'
139             'unsupported properties' | Sort.by(Sort.Direction.ASC, 'unsupported') | 'Invalid sorting'
140             'missing required sort'  | Sort.by(Sort.Direction.ASC, 'anchor')      | 'Missing mandatory sort'
141     }
142
143     def 'Error Handling: Invalid simple payload filter.'() {
144         given: 'invalid simple payload filter'
145             def inavlidSimplePayloadFilter = 'invalid-json'
146         when: 'search criteria is created without invalid simple payload filter'
147             SearchCriteria.builder()
148                 .dataspaceName(myDataspace)
149                 .anchorName(myAnchorName)
150                 .pagination(0, 1)
151                 .simplePayloadFilter(inavlidSimplePayloadFilter)
152                 .build()
153         then: 'exception is thrown'
154             thrown(IllegalArgumentException)
155     }
156
157 }