Merge branch 'main' into mocha

This commit is contained in:
Christian Georgi
2022-10-05 16:16:51 +02:00
committed by GitHub
23 changed files with 662 additions and 6942 deletions

View File

@@ -1,15 +1,15 @@
{ {
"extends": "eslint:recommended", "extends": [
"eslint:recommended",
"plugin:@sap/cds/recommended"
],
"env": { "env": {
"browser": true, "browser": true,
"es2022": true,
"node": true, "node": true,
"es6": true,
"jest": true, "jest": true,
"mocha": true "mocha": true
}, },
"parserOptions": {
"ecmaVersion": 2020
},
"globals": { "globals": {
"SELECT": true, "SELECT": true,
"INSERT": true, "INSERT": true,

2
.gitignore vendored
View File

@@ -18,3 +18,5 @@ reviews/msg-box
reviews/db/test.db reviews/db/test.db
*.openapi3.json *.openapi3.json
*.sqlite
*.db

12
.vscode/settings.json vendored
View File

@@ -14,5 +14,13 @@
"**/odata-v4/okra/**" "**/odata-v4/okra/**"
] ]
}, },
"mochaExplorer.parallel": true "mochaExplorer.parallel": true,
} "eslint.validate": [
"cds",
"csn",
"csv",
"csv (semicolon)",
"tsv",
"tab"
]
}

View File

@@ -56,7 +56,7 @@ const books = Vue.createApp ({
} catch (err) { books.user = { id: err.message } } } catch (err) { books.user = { id: err.message } }
}, },
} }
}).mount("#app") }).mount('#app')
books.getUserInfo() books.getUserInfo()
books.fetch() // initially fill list of books books.fetch() // initially fill list of books
@@ -65,3 +65,25 @@ document.addEventListener('keydown', (event) => {
// hide user info on request // hide user info on request
if (event.key === 'u') books.user = undefined if (event.key === 'u') books.user = undefined
}) })
axios.interceptors.request.use(csrfToken)
function csrfToken (request) {
if (request.method === 'head' || request.method === 'get') return request
if ('csrfToken' in document) {
request.headers['x-csrf-token'] = document.csrfToken
return request
}
return fetchToken().then(token => {
document.csrfToken = token
request.headers['x-csrf-token'] = document.csrfToken
return request
}).catch(_ => {
document.csrfToken = null // set mark to not try again
return request
})
function fetchToken() {
return axios.get('/', { headers: { 'x-csrf-token': 'fetch' } })
.then(res => res.headers['x-csrf-token'])
}
}

View File

@@ -1,9 +1,10 @@
const cds = require('@sap/cds') const cds = require('@sap/cds/lib')
module.exports = cds.service.impl (function(){ module.exports = class AdminService extends cds.ApplicationService { init(){
this.before ('NEW','Authors', genid) this.before ('NEW','Authors', genid)
this.before ('NEW','Books', genid) this.before ('NEW','Books', genid)
}) return super.init()
}}
/** Generate primary keys for target entity in request */ /** Generate primary keys for target entity in request */
async function genid (req) { async function genid (req) {

View File

@@ -2,7 +2,8 @@ const cds = require('@sap/cds')
class CatalogService extends cds.ApplicationService { init(){ class CatalogService extends cds.ApplicationService { init(){
const { Books } = this.entities ('sap.capire.bookshop') const { Books } = cds.entities ('sap.capire.bookshop')
const { ListOfBooks } = this.entities
// Reduce stock of ordered books if available stock suffices // Reduce stock of ordered books if available stock suffices
this.on ('submitOrder', async req => { this.on ('submitOrder', async req => {
@@ -18,7 +19,7 @@ class CatalogService extends cds.ApplicationService { init(){
}) })
// Add some discount for overstocked books // Add some discount for overstocked books
this.after ('READ','ListOfBooks', each => { this.after ('READ', ListOfBooks, each => {
if (each.stock > 111) each.title += ` -- 11% discount!` if (each.stock > 111) each.title += ` -- 11% discount!`
}) })

View File

@@ -5,7 +5,7 @@ service UserService {
/** /**
* The current user * The current user
*/ */
@odata.singleton entity me { @odata.singleton entity me @cds.persistence.skip {
id : String; // user id id : String; // user id
locale : String; locale : String;
tenant : String; tenant : String;

View File

@@ -19,4 +19,4 @@ module.exports = cds.server
// For didactic reasons in capire // For didactic reasons in capire
const { ReviewsService, OrdersService } = cds.requires const { ReviewsService, OrdersService } = cds.requires
if (!ReviewsService.credentials && !OrdersService.credentials) cds.requires.messaging = false if (!ReviewsService?.credentials && !OrdersService?.credentials) cds.requires.messaging = false

View File

@@ -2,12 +2,12 @@
* Exposes data + entity metadata * Exposes data + entity metadata
*/ */
@requires:'authenticated-user' @requires:'authenticated-user'
service DataService @( path:'-data' ) { @odata service DataService @( path:'-data' ) {
/** /**
* Metadata like name and columns/elements * Metadata like name and columns/elements
*/ */
entity Entities { entity Entities @cds.persistence.skip {
key name : String; key name : String;
columns: Composition of many { columns: Composition of many {
name : String; name : String;
@@ -19,7 +19,7 @@ service DataService @( path:'-data' ) {
/** /**
* The actual data, organized by column name * The actual data, organized by column name
*/ */
entity Data { entity Data @cds.persistence.skip {
record : array of { record : array of {
column : String; column : String;
data : String; data : String;

View File

@@ -33,7 +33,7 @@ annotate CatalogService.Books with @(UI : {
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
// //
// Books Object Page // Books List Page
// //
annotate CatalogService.Books with @(UI : { annotate CatalogService.Books with @(UI : {
SelectionFields : [ SelectionFields : [

View File

@@ -10,40 +10,31 @@ using { sap.common } from '@capire/common';
// Books Lists // Books Lists
// //
annotate my.Books with @( annotate my.Books with @(
Common.SemanticKey : [ID], Common.SemanticKey : [ID],
UI : { UI : {
Identification : [{Value : title}], Identification : [{ Value: title }],
SelectionFields : [ SelectionFields : [
ID, ID,
author_ID, author_ID,
price, price,
currency_code currency_code
], ],
LineItem : [ LineItem : [
{ { Value: ID, Label: '{i18n>Title}' },
Value : ID, { Value: author.ID, Label: '{i18n>Author}' },
Label : '{i18n>Title}' { Value: genre.name },
}, { Value: stock },
{ { Value: price },
Value : author.ID, { Value: currency.symbol, Label: ' ' },
Label : '{i18n>Author}' ]
}, }
{Value : genre.name},
{Value : stock},
{Value : price},
{
Value : currency.symbol,
Label : ' '
},
]
}
) { ) {
ID @Common: { ID @Common: {
SemanticObject : 'Books', SemanticObject : 'Books',
Text: title, Text: title,
TextArrangement : #TextOnly TextArrangement : #TextOnly
}; };
author @ValueList.entity : 'Authors'; author @ValueList.entity : 'Authors';
}; };
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -51,10 +42,10 @@ annotate my.Books with @(
// Books Details // Books Details
// //
annotate my.Books with @(UI : {HeaderInfo : { annotate my.Books with @(UI : {HeaderInfo : {
TypeName : '{i18n>Book}', TypeName : '{i18n>Book}',
TypeNamePlural : '{i18n>Books}', TypeNamePlural : '{i18n>Books}',
Title : {Value : title}, Title : { Value: title },
Description : {Value : author.name} Description : { Value: author.name }
}, }); }, });
@@ -63,19 +54,13 @@ annotate my.Books with @(UI : {HeaderInfo : {
// Books Elements // Books Elements
// //
annotate my.Books with { annotate my.Books with {
ID @title : '{i18n>ID}'; ID @title: '{i18n>ID}';
title @title : '{i18n>Title}'; title @title: '{i18n>Title}';
genre @title : '{i18n>Genre}' @Common : { genre @title: '{i18n>Genre}' @Common: { Text: genre.name, TextArrangement: #TextOnly };
Text : genre.name, author @title: '{i18n>Author}' @Common: { Text: author.name, TextArrangement: #TextOnly };
TextArrangement : #TextOnly price @title: '{i18n>Price}' @Measures.ISOCurrency : currency_code;
}; stock @title: '{i18n>Stock}';
author @title : '{i18n>Author}' @Common : { descr @UI.MultiLineText;
Text : author.name,
TextArrangement : #TextOnly
};
price @title : '{i18n>Price}' @Measures.ISOCurrency : currency_code;
stock @title : '{i18n>Stock}';
descr @UI.MultiLineText;
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -83,17 +68,17 @@ annotate my.Books with {
// Genres List // Genres List
// //
annotate my.Genres with @( annotate my.Genres with @(
Common.SemanticKey : [name], Common.SemanticKey : [name],
UI : { UI : {
SelectionFields : [name], SelectionFields : [name],
LineItem : [ LineItem : [
{Value : name}, { Value: name },
{ {
Value : parent.name, Value : parent.name,
Label : 'Main Genre' Label: 'Main Genre'
}, },
], ],
} }
); );
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -101,18 +86,18 @@ annotate my.Genres with @(
// Genre Details // Genre Details
// //
annotate my.Genres with @(UI : { annotate my.Genres with @(UI : {
Identification : [{Value : name}], Identification : [{ Value: name}],
HeaderInfo : { HeaderInfo : {
TypeName : '{i18n>Genre}', TypeName : '{i18n>Genre}',
TypeNamePlural : '{i18n>Genres}', TypeNamePlural : '{i18n>Genres}',
Title : {Value : name}, Title : { Value: name },
Description : {Value : ID} Description : { Value: ID }
}, },
Facets : [{ Facets : [{
$Type : 'UI.ReferenceFacet', $Type : 'UI.ReferenceFacet',
Label : '{i18n>SubGenres}', Label : '{i18n>SubGenres}',
Target : 'children/@UI.LineItem' Target : 'children/@UI.LineItem'
}, ], }, ],
}); });
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -120,8 +105,8 @@ annotate my.Genres with @(UI : {
// Genres Elements // Genres Elements
// //
annotate my.Genres with { annotate my.Genres with {
ID @title : '{i18n>ID}'; ID @title: '{i18n>ID}';
name @title : '{i18n>Genre}'; name @title: '{i18n>Genre}';
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -129,24 +114,24 @@ annotate my.Genres with {
// Authors List // Authors List
// //
annotate my.Authors with @( annotate my.Authors with @(
Common.SemanticKey : [ID], Common.SemanticKey : [ID],
UI : { UI : {
Identification : [{Value : name}], Identification : [{ Value: name}],
SelectionFields : [name], SelectionFields : [name],
LineItem : [ LineItem : [
{Value : ID}, { Value: ID },
{Value : dateOfBirth}, { Value: dateOfBirth },
{Value : dateOfDeath}, { Value: dateOfDeath },
{Value : placeOfBirth}, { Value: placeOfBirth },
{Value : placeOfDeath}, { Value: placeOfDeath },
], ],
} }
) { ) {
ID @Common: { ID @Common: {
SemanticObject : 'Authors', SemanticObject : 'Authors',
Text: name, Text: name,
TextArrangement : #TextOnly, TextArrangement : #TextOnly,
}; };
}; };
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -154,16 +139,16 @@ annotate my.Authors with @(
// Author Details // Author Details
// //
annotate my.Authors with @(UI : { annotate my.Authors with @(UI : {
HeaderInfo : { HeaderInfo : {
TypeName : '{i18n>Author}', TypeName : '{i18n>Author}',
TypeNamePlural : '{i18n>Authors}', TypeNamePlural : '{i18n>Authors}',
Title : {Value : name}, Title : { Value: name },
Description : {Value : dateOfBirth} Description : { Value: dateOfBirth }
}, },
Facets : [{ Facets : [{
$Type : 'UI.ReferenceFacet', $Type : 'UI.ReferenceFacet',
Target : 'books/@UI.LineItem' Target : 'books/@UI.LineItem'
}, ], }, ],
}); });
@@ -172,12 +157,12 @@ annotate my.Authors with @(UI : {
// Authors Elements // Authors Elements
// //
annotate my.Authors with { annotate my.Authors with {
ID @title : '{i18n>ID}'; ID @title: '{i18n>ID}';
name @title : '{i18n>Name}'; name @title: '{i18n>Name}';
dateOfBirth @title : '{i18n>DateOfBirth}'; dateOfBirth @title: '{i18n>DateOfBirth}';
dateOfDeath @title : '{i18n>DateOfDeath}'; dateOfDeath @title: '{i18n>DateOfDeath}';
placeOfBirth @title : '{i18n>PlaceOfBirth}'; placeOfBirth @title: '{i18n>PlaceOfBirth}';
placeOfDeath @title : '{i18n>PlaceOfDeath}'; placeOfDeath @title: '{i18n>PlaceOfDeath}';
} }
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -185,18 +170,18 @@ annotate my.Authors with {
// Languages List // Languages List
// //
annotate common.Languages with @( annotate common.Languages with @(
Common.SemanticKey : [code], Common.SemanticKey : [code],
Identification : [{Value : code}], Identification : [{ Value: code}],
UI : { UI : {
SelectionFields : [ SelectionFields : [
name, name,
descr descr
], ],
LineItem : [ LineItem : [
{Value : code}, { Value: code },
{Value : name}, { Value: name },
], ],
} }
); );
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -204,22 +189,22 @@ annotate common.Languages with @(
// Language Details // Language Details
// //
annotate common.Languages with @(UI : { annotate common.Languages with @(UI : {
HeaderInfo : { HeaderInfo : {
TypeName : '{i18n>Language}', TypeName : '{i18n>Language}',
TypeNamePlural : '{i18n>Languages}', TypeNamePlural : '{i18n>Languages}',
Title : {Value : name}, Title : { Value: name },
Description : {Value : descr} Description : { Value: descr }
}, },
Facets : [{ Facets : [{
$Type : 'UI.ReferenceFacet', $Type : 'UI.ReferenceFacet',
Label : '{i18n>Details}', Label : '{i18n>Details}',
Target : '@UI.FieldGroup#Details' Target : '@UI.FieldGroup#Details'
}, ], }, ],
FieldGroup #Details : {Data : [ FieldGroup #Details : {Data : [
{Value : code}, { Value: code },
{Value : name}, { Value: name },
{Value : descr} { Value: descr }
]}, ]},
}); });
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -227,19 +212,19 @@ annotate common.Languages with @(UI : {
// Currencies List // Currencies List
// //
annotate common.Currencies with @( annotate common.Currencies with @(
Common.SemanticKey : [code], Common.SemanticKey : [code],
Identification : [{Value : code}], Identification : [{ Value: code}],
UI : { UI : {
SelectionFields : [ SelectionFields : [
name, name,
descr descr
], ],
LineItem : [ LineItem : [
{Value : descr}, { Value: descr },
{Value : symbol}, { Value: symbol },
{Value : code}, { Value: code },
], ],
} }
); );
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -247,35 +232,35 @@ annotate common.Currencies with @(
// Currency Details // Currency Details
// //
annotate common.Currencies with @(UI : { annotate common.Currencies with @(UI : {
HeaderInfo : { HeaderInfo : {
TypeName : '{i18n>Currency}', TypeName : '{i18n>Currency}',
TypeNamePlural : '{i18n>Currencies}', TypeNamePlural : '{i18n>Currencies}',
Title : {Value : descr}, Title : { Value: descr },
Description : {Value : code} Description : { Value: code }
},
Facets : [
{
$Type : 'UI.ReferenceFacet',
Label : '{i18n>Details}',
Target : '@UI.FieldGroup#Details'
}, },
Facets : [ {
{ $Type : 'UI.ReferenceFacet',
$Type : 'UI.ReferenceFacet', Label : '{i18n>Extended}',
Label : '{i18n>Details}', Target : '@UI.FieldGroup#Extended'
Target : '@UI.FieldGroup#Details' },
}, ],
{ FieldGroup #Details : {Data : [
$Type : 'UI.ReferenceFacet', { Value: name },
Label : '{i18n>Extended}', { Value: symbol },
Target : '@UI.FieldGroup#Extended' { Value: code },
}, { Value: descr }
], ]},
FieldGroup #Details : {Data : [ FieldGroup #Extended : {Data : [
{Value : name}, { Value: numcode },
{Value : symbol}, { Value: minor },
{Value : code}, { Value: exponent }
{Value : descr} ]},
]},
FieldGroup #Extended : {Data : [
{Value : numcode},
{Value : minor},
{Value : exponent}
]},
}); });
//////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////
@@ -283,7 +268,7 @@ annotate common.Currencies with @(UI : {
// Currencies Elements // Currencies Elements
// //
annotate common.Currencies with { annotate common.Currencies with {
numcode @title : '{i18n>NumCode}'; numcode @title: '{i18n>NumCode}';
minor @title : '{i18n>MinorUnit}'; minor @title: '{i18n>MinorUnit}';
exponent @title : '{i18n>Exponent}'; exponent @title: '{i18n>Exponent}';
} }

View File

@@ -43,10 +43,10 @@
"[production]": { "[production]": {
"model": "db/hana" "model": "db/hana"
} }
},
"hana": {
"deploy-format": "hdbtable"
} }
},
"hana": {
"deploy-format": "hdbtable"
} }
} }
} }

View File

@@ -12,23 +12,8 @@
"devDependencies": { "devDependencies": {
"@types/jest": "*", "@types/jest": "*",
"@types/node": "*", "@types/node": "*",
"ts-jest": "^27.0.2",
"typescript": "^4.3.5" "typescript": "^4.3.5"
}, },
"jest": {
"testEnvironment": "node",
"preset": "ts-jest",
"globals": {
"ts-jest": {
"diagnostics": {
"_comment": "see https://githubmemory.com/repo/kulshekhar/ts-jest/issues/2722",
"ignoreCodes": [
151001
]
}
}
}
},
"eslintConfig": { "eslintConfig": {
"extends": "eslint:recommended", "extends": "eslint:recommended",
"env": { "env": {

View File

@@ -0,0 +1,13 @@
const cds = require ('@sap/cds')
describe('Hello world!', () => {
beforeAll (()=> process.env.CDS_TYPESCRIPT = true)
afterAll (()=> delete process.env.CDS_TYPESCRIPT)
const {GET} = cds.test.in(__dirname,'../srv').run('serve', 'world.cds')
it('should say hello with class impl', async () => {
const {data} = await GET`/say/hello(to='world')`
expect(data.value).toMatch(/Hello world.*typescript.*/i)
})
})

View File

@@ -1,15 +0,0 @@
process.env.CDS_TYPESCRIPT = 'true';
import * as cds from '@sap/cds';
//@ts-ignore
const {GET} = cds.test.in(__dirname,'../srv').run('serve', 'world.cds');
describe('Hello world!', () => {
afterAll(() => { delete process.env.CDS_TYPESCRIPT; });
it('should say hello with class impl from a typescript file', async () => {
const {data} = await GET`/say/hello(to='world')`
expect(data.value).toMatch(/Hello world.*typescript.*/i)
})
})

View File

@@ -16,11 +16,12 @@ using { OrdersService } from '../srv/orders-service';
@odata.draft.enabled @odata.draft.enabled
annotate OrdersService.Orders with @( annotate OrdersService.Orders with @(
UI: { UI: {
SelectionFields: [ createdAt, createdBy ], SelectionFields: [ createdBy ],
LineItem: [ LineItem: [
{Value: OrderNo, Label:'OrderNo'}, {Value: OrderNo, Label:'OrderNo'},
{Value: buyer, Label:'Customer'}, {Value: buyer, Label:'Customer'},
{Value: createdAt, Label:'Date'} {Value: currency.symbol, Label:'Currency'},
{Value: createdAt, Label:'Date'},
], ],
HeaderInfo: { HeaderInfo: {
TypeName: 'Order', TypeNamePlural: 'Orders', TypeName: 'Order', TypeNamePlural: 'Orders',

View File

@@ -13,7 +13,7 @@
applications: { applications: {
"manage-orders": { "manage-orders": {
title: "Manage Orders", title: "Manage Orders",
description: "... testing FE v42", description: "CAP Sample App",
additionalInformation: "SAPUI5.Component=orders", additionalInformation: "SAPUI5.Component=orders",
applicationType : "URL", applicationType : "URL",
url: "/orders/webapp", url: "/orders/webapp",

View File

@@ -3,8 +3,8 @@
"sap.app": { "sap.app": {
"id": "orders", "id": "orders",
"type": "application", "type": "application",
"title": "Order Books", "title": "Order Management",
"description": "Sample Application", "description": "CAP Sample Application",
"i18n": "i18n/i18n.properties", "i18n": "i18n/i18n.properties",
"dataSources": { "dataSources": {
"OrdersService": { "OrdersService": {

View File

@@ -2,7 +2,7 @@ using { Currency, User, managed, cuid } from '@sap/cds/common';
namespace sap.capire.orders; namespace sap.capire.orders;
entity Orders : cuid, managed { entity Orders : cuid, managed {
OrderNo : String @title:'Order Number'; //> readable key OrderNo : String(22) @title:'Order Number'; //> readable key
Items : Composition of many { Items : Composition of many {
key ID : UUID; key ID : UUID;
product : Association to Products; product : Association to Products;

7029
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,15 @@
"@sap/cds": ">=5.5.3" "@sap/cds": ">=5.5.3"
}, },
"workspaces": [ "workspaces": [
"./*/" "./bookshop",
"./bookstore",
"./common",
"./data-viewer",
"./fiori",
"./hello",
"./media",
"./orders",
"./reviews"
], ],
"devDependencies": { "devDependencies": {
"axios": "^0", "axios": "^0",

View File

@@ -411,18 +411,67 @@ describe('cds.ql → cqn', () => {
] ]
}}) }})
expect ( const ql_with_groups_fix = !!cds.ql.Query.prototype.flat
SELECT.from(Foo).where({x:1,or:{y:2}}) if (ql_with_groups_fix) {
).to.eql (
CQL`SELECT from Foo where x=1 or y=2` expect (
).to.eql ({ SELECT: { SELECT.from(Foo).where({x:1}).or({y:2}).and({z:3})
from: {ref:['Foo']}, ).to.eql ({ SELECT: {
where: [ from: {ref:['Foo']},
{ref:['x']}, '=', {val:1}, where: [
'or', {ref:['x']}, '=', {val:1},
{ref:['y']}, '=', {val:2} 'or',
] {ref:['y']}, '=', {val:2},
}}) 'and',
{ref:['z']}, '=', {val:3},
]
}})
expect (
SELECT.from(Foo).where({x:1,or:{y:2}}).and({z:3})
).to.eql ({ SELECT: {
from: {ref:['Foo']},
where: [
{xpr:[
{ref:['x']}, '=', {val:1},
'or',
{ref:['y']}, '=', {val:2},
]},
'and',
{ref:['z']}, '=', {val:3},
]
}})
expect (
SELECT.from(Foo).where({a:1}).or({x:1,or:{y:2}}).and({z:3})
).to.eql ({ SELECT: {
from: {ref:['Foo']},
where: [
{ref:['a']}, '=', {val:1},
'or',
{xpr:[
{ref:['x']}, '=', {val:1},
'or',
{ref:['y']}, '=', {val:2},
]},
'and',
{ref:['z']}, '=', {val:3},
]
}})
expect (
{ SELECT: SELECT.from(Foo).where({x:1,or:{y:2}}).SELECT }
).to.eql ({ SELECT: {
from: {ref:['Foo']},
where: [
{ref:['x']}, '=', {val:1},
'or',
{ref:['y']}, '=', {val:2},
]
}})
}
expect ( expect (
SELECT.from(Foo).where({x:1,and:{y:2}}).or({z:3}) SELECT.from(Foo).where({x:1,and:{y:2}}).or({z:3})

View File

@@ -5,21 +5,10 @@ describe('cap/samples - Localized Data', () => {
else cds.User = cds.User.Privileged // hard core monkey patch for older cds releases else cds.User = cds.User.Privileged // hard core monkey patch for older cds releases
it('serves localized $metadata documents', async () => { it('serves localized $metadata documents', async () => {
const { data } = await GET`/browse/$metadata?sap-language=de` const { data } = await GET(`/browse/$metadata?sap-language=de`, { headers: { 'accept-language': 'de' }})
expect(data).to.contain('<Annotation Term="Common.Label" String="Währung"/>') expect(data).to.contain('<Annotation Term="Common.Label" String="Währung"/>')
}) })
it('supports sap-language param', async () => {
const { data } = await GET(`/browse/Books?$select=title,author` + '&sap-language=de')
expect(data.value).to.containSubset([
{ title: 'Sturmhöhe', author: 'Emily Brontë' },
{ title: 'Jane Eyre', author: 'Charlotte Brontë' },
{ title: 'The Raven', author: 'Edgar Allen Poe' },
{ title: 'Eleonora', author: 'Edgar Allen Poe' },
{ title: 'Catweazle', author: 'Richard Carpenter' },
])
})
it('supports accept-language header', async () => { it('supports accept-language header', async () => {
const { data } = await GET(`/browse/Books?$select=title,author`, { const { data } = await GET(`/browse/Books?$select=title,author`, {
headers: { 'Accept-Language': 'de' }, headers: { 'Accept-Language': 'de' },