@@ -3,29 +3,9 @@ const cds = require('@sap/cds')
33describe ( 'CatalogService' , ( ) => {
44 const { GET , axios } = cds . test ( )
55
6- describe ( 'called by alice (no ReadBooks )' , ( ) => {
6+ describe ( 'called by reader (cap.Reader policy assigned )' , ( ) => {
77 beforeAll ( ( ) => {
8- axios . defaults . auth = { username : 'alice' , password : '' }
9- } )
10-
11- it ( '/Books should return status 403' , async ( ) => {
12- expect . assertions ( 1 ) ;
13- return ( GET `/odata/v4/catalog/Books` ) . catch ( error => {
14- expect ( error . response . status ) . toBe ( 403 )
15- } )
16- } )
17-
18- it ( '/ListOfBooks should return status 403' , async ( ) => {
19- expect . assertions ( 1 ) ;
20- return ( GET `/odata/v4/catalog/ListOfBooks` ) . catch ( error => {
21- expect ( error . response . status ) . toBe ( 403 )
22- } )
23- } )
24- } )
25-
26- describe ( 'called by bob (cap.ReadBooks policy assigned)' , ( ) => {
27- beforeAll ( ( ) => {
28- axios . defaults . auth = { username : 'bob' , password : '' }
8+ axios . defaults . auth = { username : 'reader' , password : '' }
299 } )
3010
3111 it ( '/Books should return all Books' , async ( ) => {
@@ -53,41 +33,16 @@ describe('CatalogService', () => {
5333 } )
5434 } )
5535
56- describe ( 'called by carol (cap.Zealot policy assigned)' , ( ) => {
36+ describe ( 'called by juniorReader (local.JuniorReader policy assigned)' , ( ) => {
5737 beforeAll ( ( ) => {
58- axios . defaults . auth = { username : 'carol ' , password : '' }
38+ axios . defaults . auth = { username : 'juniorReader ' , password : '' }
5939 } )
6040
6141 /**
62- * - access to The Raven is granted as its description contains religious references
63- */
64- it ( '/Books should return 1 Book (The Raven)' , async ( ) => {
65- const { status, data } = await GET `/odata/v4/catalog/Books`
66- expect ( status ) . toBe ( 200 )
67- expect ( data . value ?. length ) . toBe ( 1 )
68- expect ( data . value [ 0 ] . title ) . toEqual ( 'The Raven' )
69- } )
70-
71- /**
72- * On /ListOfBooks, the AMS description attribute is not mapped to a cds element, so access to The Raven is forbidden
73- */
74- it ( '/ListOfBooks should return 403 because the AMS description attribute is not mapped to a cds element' , async ( ) => {
75- expect . hasAssertions ( ) ;
76- return ( GET `/odata/v4/catalog/ListOfBooks` ) . catch ( error => {
77- expect ( error . response . status ) . toBe ( 403 )
78- } ) ;
79- } )
80- } )
81-
82- describe ( 'called by dave (cap.JuniorReader policy assigned)' , ( ) => {
83- beforeAll ( ( ) => {
84- axios . defaults . auth = { username : 'dave' , password : '' }
85- } )
86-
87- /**
88- * The JuniorReader policy adds attribute filters for genre to the query:
42+ * The JuniorReader policy restricts to Fairy Tale, Fantasy, and Mystery genres:
8943 * - access to Catweazle is granted as its genre is Fantasy
90- * - access to The Raven, Eleonora is granted as their genre is Mystery
44+ * - access to The Raven and Eleonora is granted as their genre is Mystery
45+ * - Fairy Tale books would also be included but there are none in the data
9146 */
9247 it ( '/Books should return 3 Books (Catweazle, The Raven, Eleonora)' , async ( ) => {
9348 const { status, data } = await GET `/odata/v4/catalog/Books`
@@ -98,15 +53,15 @@ describe('CatalogService', () => {
9853 expect ( data . value ) . toContainEqual ( expect . objectContaining ( { title : 'Eleonora' } ) )
9954 } )
10055
101- // Book 201 = Wuthering Heights
56+ // Book 201 = Wuthering Heights (Drama genre - not allowed)
10257 it ( '/Books/201/getStockedValue() should be forbidden' , async ( ) => {
10358 expect . hasAssertions ( ) ;
10459 return ( GET `/odata/v4/catalog/Books/201/getStockedValue()` ) . catch ( error => {
10560 expect ( error . response . status ) . toBe ( 403 )
10661 } )
10762 } )
10863
109- // Book 271 = Catweazle
64+ // Book 271 = Catweazle (Fantasy genre - allowed)
11065 it ( '/Books/271/getStockedValue() should return 3300' , async ( ) => {
11166 const { status, data } = await GET `/odata/v4/catalog/Books/271/getStockedValue()`
11267 expect ( status ) . toBe ( 200 )
@@ -122,72 +77,16 @@ describe('CatalogService', () => {
12277 } )
12378 } )
12479
125- describe ( 'called by erin (BestsellerReader)' , ( ) => {
126- beforeAll ( ( ) => {
127- axios . defaults . auth = { username : 'erin' , password : '' }
128- } )
129-
130- it ( '/Books should return 2 Books (Wuthering Heights, Jane Eyre)' , async ( ) => {
131- const { status, data } = await GET `/odata/v4/catalog/Books`
132- expect ( status ) . toBe ( 200 )
133- expect ( data . value ?. length ) . toBe ( 2 )
134- const bookTitles = data . value . map ( book => book . title )
135- expect ( bookTitles ) . toContain ( 'Wuthering Heights' )
136- expect ( bookTitles ) . toContain ( 'Jane Eyre' )
137- } )
138-
139- it ( '/ListOfBooks should return 2 Books (Wuthering Heights, Jane Eyre)' , async ( ) => {
140- const { status, data } = await GET `/odata/v4/catalog/ListOfBooks`
141- expect ( status ) . toBe ( 200 )
142- expect ( data . value ?. length ) . toBe ( 2 )
143- const bookTitles = data . value . map ( book => book . title )
144- expect ( bookTitles ) . toContain ( 'Wuthering Heights' )
145- expect ( bookTitles ) . toContain ( 'Jane Eyre' )
146- } )
147- } )
148-
149- describe ( 'called by fred (Zealot, BestsellerReader)' , ( ) => {
150- beforeAll ( ( ) => {
151- axios . defaults . auth = { username : 'fred' , password : '' }
152- } )
153-
154- /**
155- * Combination of two policies with different attribute filters should yield union of both result sets:
156- * - via Zealot policy access to The Raven is granted as its description contains religious references
157- * - via BestsellerReader policy access to Wuthering Heights and Jane Eyre is granted as they are low on stock
158- */
159- it ( '/Books should return 3 Books (Wuthering Heights, Jane Eyre, The Raven)' , async ( ) => {
160- const { status, data } = await GET `/odata/v4/catalog/Books`
161- expect ( status ) . toBe ( 200 )
162- expect ( data . value ?. length ) . toBe ( 3 )
163- const bookTitles = data . value . map ( book => book . title )
164- expect ( bookTitles ) . toContain ( 'Wuthering Heights' )
165- expect ( bookTitles ) . toContain ( 'Jane Eyre' )
166- expect ( bookTitles ) . toContain ( 'The Raven' )
167- } )
168-
169- /**
170- * On /ListOfBooks, the AMS description attribute is not mapped to a cds element, so access via the Zealot policy is forbidden
171- */
172- it ( '/ListOfBooks should return 2 Books (Wuthering Heights, Jane Eyre)' , async ( ) => {
173- const { status, data } = await GET `/odata/v4/catalog/ListOfBooks`
174- expect ( status ) . toBe ( 200 )
175- expect ( data . value ?. length ) . toBe ( 2 )
176- const bookTitles = data . value . map ( book => book . title )
177- expect ( bookTitles ) . toContain ( 'Wuthering Heights' )
178- expect ( bookTitles ) . toContain ( 'Jane Eyre' )
179- } )
180- } )
181-
18280 describe ( 'called by technicalUser (calling ReadCatalog API policy)' , ( ) => {
18381 beforeAll ( ( ) => {
18482 axios . defaults . auth = { username : 'technicalUser' , password : '' }
18583 } )
18684
18785 /**
188- * The ReadCatalog API policy grants access to books with stock < 30
86+ * The ReadCatalog API policy restricts to genres NOT IN (Mystery, Romance, Thriller, Dystopia)
87+ * The remaining list includes Drama (Wuthering Heights, Jane Eyre) and Fantasy (Catweazle)
18988 */
190- it ( '/Books should return 3 Books with stock < 30 (Catweazle, Wuthering Heights, Jane Eyre)' , async ( ) => {
89+ it ( '/Books should return 3 Books (Catweazle, Wuthering Heights, Jane Eyre)' , async ( ) => {
19190 const { status, data } = await GET `/odata/v4/catalog/Books`
19291 expect ( status ) . toBe ( 200 )
19392 expect ( data . value ?. length ) . toBe ( 3 )
@@ -196,31 +95,31 @@ describe('CatalogService', () => {
19695 expect ( data . value ) . toContainEqual ( expect . objectContaining ( { title : 'Jane Eyre' } ) )
19796 } )
19897
199- // Book 252 = Eleonora
98+ // Book 252 = Eleonora (Mystery genre - forbidden by ReadCatalog policy)
20099 it ( '/Books/252/getStockedValue() should be forbidden' , async ( ) => {
201100 expect . hasAssertions ( ) ;
202101 return ( GET `/odata/v4/catalog/Books/252/getStockedValue()` ) . catch ( error => {
203102 expect ( error . response . status ) . toBe ( 403 )
204103 } )
205104 } )
206105
207- // Book 271 = Catweazle
208- it ( '/Books/271/getStockedValue() should return 7770 ' , async ( ) => {
106+ // Book 271 = Catweazle (Fantasy genre - allowed by ReadCatalog policy)
107+ it ( '/Books/271/getStockedValue() should return 3300 ' , async ( ) => {
209108 const { status, data } = await GET `/odata/v4/catalog/Books/271/getStockedValue()`
210109 expect ( status ) . toBe ( 200 )
211110 expect ( data . value ) . toBe ( 3300 )
212111 } )
213112 } )
214113
215- describe ( 'called by principalPropagation (cap .JuniorReader policy limited to ReadCatalog API policy)' , ( ) => {
114+ describe ( 'called by principalPropagation (local .JuniorReader policy limited to ReadCatalog API policy)' , ( ) => {
216115 beforeAll ( ( ) => {
217116 axios . defaults . auth = { username : 'principalPropagation' , password : '' }
218117 } )
219118
220119 /**
221- * The JuniorReader policy adds attribute filters for genre to the query:
222- * - access to Catweazle is granted as its genre is Fantasy
223- * - access to The Raven and Eleonora is granted as their genre is Mystery but filtered out by stock < 30 from ReadCatalog policy
120+ * The JuniorReader policy restricts to Fairy Tale, Fantasy, and Mystery genres
121+ * The ReadCatalog API policy restricts to genres NOT IN (Mystery, Romance, Thriller, Dystopia)
122+ * The intersection yields only Fantasy genre books ( Mystery is excluded by ReadCatalog), which is Catweazle
224123 */
225124 it ( '/Books should return 1 Book (Catweazle)' , async ( ) => {
226125 const { status, data } = await GET `/odata/v4/catalog/Books`
@@ -229,16 +128,16 @@ describe('CatalogService', () => {
229128 expect ( data . value ) . toContainEqual ( expect . objectContaining ( { title : 'Catweazle' } ) )
230129 } )
231130
232- // Book 252 = Eleonora
131+ // Book 252 = Eleonora (Mystery genre - allowed by JuniorReader but forbidden by ReadCatalog API policy)
233132 it ( '/Books/252/getStockedValue() should be forbidden' , async ( ) => {
234133 expect . hasAssertions ( ) ;
235134 return ( GET `/odata/v4/catalog/Books/252/getStockedValue()` ) . catch ( error => {
236135 expect ( error . response . status ) . toBe ( 403 )
237136 } )
238137 } )
239138
240- // Book 271 = Catweazle
241- it ( '/Books/271/getStockedValue() should return 7770 ' , async ( ) => {
139+ // Book 271 = Catweazle (Fantasy genre - allowed by both policies)
140+ it ( '/Books/271/getStockedValue() should return 3300 ' , async ( ) => {
242141 const { status, data } = await GET `/odata/v4/catalog/Books/271/getStockedValue()`
243142 expect ( status ) . toBe ( 200 )
244143 expect ( data . value ) . toBe ( 3300 )
0 commit comments