Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Commit a7794a4

Browse files
committed
update tests
1 parent 340edd4 commit a7794a4

File tree

5 files changed

+340
-48
lines changed

5 files changed

+340
-48
lines changed

media-store/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
"scripts": {
2424
"start": "npx cds run",
2525
"deploy": "cds deploy --to sqlite:mychinook.db",
26-
"test": "mocha test/media-store.test.js --verbose --timeout 10000"
26+
"test": "npm run deploy && cd ../ && npm run jest"
2727
},
2828
"cds": {
2929
"ACCESS_TOKEN_SECRET": "secret",

media-store/srv/user-service.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,12 @@ module.exports = async function () {
4343
return Object.assign({}, userFromDb, { roles });
4444
}
4545

46+
/**
47+
* User can only update and read his data
48+
*/
4649
this.before("UPDATE", "*", async (req) => {
4750
req.query = req.query.where({ ID: req.user.attr.ID });
4851
});
49-
5052
this.before("READ", "*", async (req) => {
5153
req.query = req.query.where({ ID: req.user.attr.ID });
5254
});

media-store/test/data/media-store.mock.js

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,4 +185,89 @@ const ALL_ALBUMS_WITH_TRACKS_BY_ARTIST = {
185185
],
186186
};
187187

188-
module.exports = { FIRST_TRACK, ALL_ALBUMS_WITH_TRACKS_BY_ARTIST };
188+
const SECOND_CUSTOMER = {
189+
"@odata.context": "$metadata#Customers/$entity",
190+
ID: 2,
191+
lastName: "Köhler",
192+
firstName: "Leonie",
193+
city: "Stuttgart",
194+
address: "Theodor-Heuss-Straße 34",
195+
country: "Germany",
196+
phone: "+49 0711 2842222",
197+
198+
};
199+
200+
const FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER = {
201+
"@odata.context": "$metadata#MarkedTracks/$entity",
202+
ID: 4,
203+
name: "Restless and Wild",
204+
composer:
205+
"F. Baltes, R.A. Smith-Diesel, S. Kaufman, U. Dirkscneider & W. Hoffman",
206+
unitPrice: 0.99,
207+
alreadyOrdered: true,
208+
album_ID: 3,
209+
genre_ID: 1,
210+
};
211+
212+
const SECOND_CUSTOMER_INVOICES = {
213+
"@odata.context": "$metadata#Invoices",
214+
value: [
215+
{
216+
ID: 1,
217+
invoiceDate: "2008-12-31T22:00:00Z",
218+
total: 1.98,
219+
status: 1,
220+
customer_ID: 2,
221+
},
222+
{
223+
ID: 12,
224+
invoiceDate: "2009-02-10T22:00:00Z",
225+
total: 13.86,
226+
status: 1,
227+
customer_ID: 2,
228+
},
229+
{
230+
ID: 67,
231+
invoiceDate: "2009-10-11T21:00:00Z",
232+
total: 8.91,
233+
status: 1,
234+
customer_ID: 2,
235+
},
236+
{
237+
ID: 196,
238+
invoiceDate: "2011-05-18T21:00:00Z",
239+
total: 1.98,
240+
status: 1,
241+
customer_ID: 2,
242+
},
243+
{
244+
ID: 219,
245+
invoiceDate: "2011-08-20T21:00:00Z",
246+
total: 3.96,
247+
status: 1,
248+
customer_ID: 2,
249+
},
250+
{
251+
ID: 241,
252+
invoiceDate: "2011-11-22T21:00:00Z",
253+
total: 5.94,
254+
status: 1,
255+
customer_ID: 2,
256+
},
257+
{
258+
ID: 293,
259+
invoiceDate: "2012-07-12T21:00:00Z",
260+
total: 0.99,
261+
status: 1,
262+
customer_ID: 2,
263+
},
264+
],
265+
};
266+
267+
module.exports = {
268+
FIRST_TRACK,
269+
ALL_ALBUMS_WITH_TRACKS_BY_ARTIST,
270+
SECOND_CUSTOMER,
271+
FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER,
272+
SECOND_CUSTOMER_INVOICES,
273+
};
Lines changed: 218 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,247 @@
11
const { GET, POST, expect } = require("../../test").run("media-store");
22
const cds = require("@sap/cds/lib");
3-
4-
class MockedUser extends cds.User {
5-
constructor(attr, roles, id) {
6-
super({ attr, _roles: [...roles], id });
7-
}
8-
}
9-
103
const {
114
FIRST_TRACK,
125
ALL_ALBUMS_WITH_TRACKS_BY_ARTIST,
6+
SECOND_CUSTOMER,
7+
FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER,
8+
SECOND_CUSTOMER_INVOICES,
139
} = require("./data/media-store.mock");
1410

11+
const fs = require("fs");
12+
13+
const DEFAULT_CONFIG = {
14+
headers: { "content-type": "application/json" },
15+
};
16+
1517
describe("Media Store services", () => {
16-
before("skipping auth", () => {
17-
cds.User = cds.User.Privileged; // skip auth
18+
const CURRENT_CUSTOMER_DATA = {
19+
ID: 2,
20+
21+
password: "some",
22+
roles: ["customer"],
23+
};
24+
const CURRENT_EMPLOYEE_DATA = {
25+
ID: 4,
26+
27+
password: "some",
28+
roles: ["employee"],
29+
};
30+
let customerAccessToken;
31+
let employeeAccessToken;
32+
33+
before("login user", async () => {
34+
customerLoginResponse = await POST(
35+
"/users/login",
36+
{
37+
email: CURRENT_CUSTOMER_DATA.email,
38+
password: CURRENT_CUSTOMER_DATA.password,
39+
},
40+
DEFAULT_CONFIG
41+
);
42+
customerAccessToken = customerLoginResponse.data.accessToken;
43+
44+
employeeLoginResponse = await POST(
45+
"/users/login",
46+
{
47+
email: CURRENT_EMPLOYEE_DATA.email,
48+
password: CURRENT_EMPLOYEE_DATA.password,
49+
},
50+
DEFAULT_CONFIG
51+
);
52+
employeeAccessToken = employeeLoginResponse.data.accessToken;
1853
});
1954

20-
it("should bootstrap the services successfully", () => {
21-
const { BrowseTracks, db } = cds.services;
55+
it("should bootstrap services successfully", () => {
56+
const {
57+
BrowseTracks,
58+
BrowseInvoices,
59+
ManageStore,
60+
Users,
61+
db,
62+
} = cds.services;
2263
const { Tracks } = BrowseTracks.entities;
2364

2465
expect(BrowseTracks).not.to.be.undefined;
66+
expect(BrowseInvoices).not.to.be.undefined;
67+
expect(ManageStore).not.to.be.undefined;
68+
expect(Users).not.to.be.undefined;
2569
expect(db).not.to.be.undefined;
2670
expect(Tracks).not.to.be.undefined;
2771
});
2872

29-
describe("Tracks", () => {
73+
describe("Users", () => {
74+
function compareAuthData(actualAuthData) {
75+
expect(actualAuthData).not.to.be.undefined;
76+
expect(actualAuthData).to.have.own.property("accessToken");
77+
expect(actualAuthData).to.have.own.property("refreshToken");
78+
expect(actualAuthData).to.have.own.property("ID");
79+
expect(actualAuthData).to.have.own.property("email");
80+
expect(actualAuthData).to.have.own.property("roles");
81+
expect(actualAuthData.ID).to.equal(CURRENT_CUSTOMER_DATA.ID);
82+
expect(actualAuthData.email).to.equal(CURRENT_CUSTOMER_DATA.email);
83+
expect(actualAuthData.roles).to.deep.equal(CURRENT_CUSTOMER_DATA.roles);
84+
}
85+
86+
it("should login user successfully", async () => {
87+
const { data: actualData } = customerLoginResponse;
88+
89+
compareAuthData(actualData);
90+
});
91+
92+
it("shouldn't login customer with invalid credentials", async () => {
93+
try {
94+
await POST(
95+
"/users/login",
96+
{
97+
email: CURRENT_CUSTOMER_DATA.email,
98+
password: "some-invalid-password",
99+
},
100+
DEFAULT_CONFIG
101+
);
102+
} catch (error) {
103+
expect(error.message).to.equal("401 - Unauthorized");
104+
}
105+
});
106+
107+
it("should refresh tokens successfully", async () => {
108+
const {
109+
data: { refreshToken },
110+
} = customerLoginResponse;
111+
const { data: actualRefreshTokensData } = await POST(
112+
"/users/refreshTokens",
113+
{
114+
refreshToken,
115+
},
116+
DEFAULT_CONFIG
117+
);
118+
119+
compareAuthData(actualRefreshTokensData);
120+
});
121+
122+
it("shouldn't refresh tokens due to invalid provided one", async () => {
123+
try {
124+
await POST(
125+
"/users/refreshTokens",
126+
{
127+
refreshToken: "some-invalid-refresh-token",
128+
},
129+
DEFAULT_CONFIG
130+
);
131+
} catch (error) {
132+
expect(error.message).to.equal("401 - Unauthorized");
133+
}
134+
});
135+
136+
it("current customer should retrieve his data", async () => {
137+
const { data: actualData } = await GET(
138+
`/users/Customers(${CURRENT_CUSTOMER_DATA.ID})`,
139+
{
140+
headers: {
141+
...DEFAULT_CONFIG.headers,
142+
authorization: "Basic " + customerAccessToken,
143+
},
144+
}
145+
);
146+
expect(actualData).not.to.be.undefined;
147+
expect(actualData).to.deep.equal(SECOND_CUSTOMER);
148+
});
149+
150+
it("current employee shouldn't have access to customer data", async () => {
151+
const someCustomerID = 15;
152+
153+
try {
154+
await GET(`/users/Customers(${someCustomerID})`, {
155+
headers: {
156+
...DEFAULT_CONFIG.headers,
157+
authorization: "Basic " + employeeAccessToken,
158+
},
159+
});
160+
} catch (error) {
161+
expect(error.message).to.equal("403 - Forbidden");
162+
}
163+
});
164+
165+
it("current customer shouldn't retrieve his data without provided access token", async () => {
166+
try {
167+
await GET(`/users/Customers(11)`, DEFAULT_CONFIG);
168+
} catch (error) {
169+
expect(error.message).to.equal("401 - Unauthorized");
170+
}
171+
});
172+
173+
it("current customer shouldn't retrieve another customer data", async () => {
174+
try {
175+
await GET(`/users/Customers(11)`, {
176+
headers: {
177+
...DEFAULT_CONFIG.headers,
178+
authorization: "Basic " + customerAccessToken,
179+
},
180+
});
181+
} catch (error) {
182+
expect(error.message).to.equal("404 - Not Found");
183+
}
184+
});
185+
});
186+
187+
describe("BrowseTracks", () => {
30188
it("should return track with ID eq 1", async () => {
31189
const { data } = await GET(
32190
"/browse-tracks/Tracks(1)?$expand=genre,album($expand=artist)"
33191
);
34192
expect(data).to.eql(FIRST_TRACK);
35193
});
194+
195+
it("should return track with ID eq 4 for second customer", async () => {
196+
const { data } = await GET("/browse-tracks/MarkedTracks(4)", {
197+
headers: {
198+
...DEFAULT_CONFIG.headers,
199+
authorization: "Basic " + customerAccessToken,
200+
},
201+
});
202+
203+
expect(data).to.eql(FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER);
204+
});
36205
});
37206

38-
describe("Albums", () => {
39-
it("should return all albums with tracks by artist", async () => {
40-
const { data } = await GET(
41-
`/browse-tracks/Albums?$filter=artist_ID eq 1&$expand=tracks`
207+
describe("BrowseInvoices", () => {
208+
async function getAllCustomerInvoices() {
209+
const { data } = await GET("/browse-invoices/Invoices", {
210+
headers: {
211+
...DEFAULT_CONFIG.headers,
212+
authorization: "Basic " + customerAccessToken,
213+
},
214+
});
215+
return data;
216+
}
217+
218+
it("should return all invoices only for current customer", async () => {
219+
const data = await getAllCustomerInvoices();
220+
221+
expect(data).to.eql(SECOND_CUSTOMER_INVOICES);
222+
});
223+
224+
it("should create invoice for current customer", async () => {
225+
const beforeData = await getAllCustomerInvoices();
226+
expect(beforeData.value.length).to.equal(
227+
SECOND_CUSTOMER_INVOICES.value.length
228+
);
229+
230+
await POST(
231+
"/browse-invoices/invoice",
232+
{ tracks: [{ ID: 3 }] },
233+
{
234+
headers: {
235+
...DEFAULT_CONFIG.headers,
236+
authorization: "Basic " + customerAccessToken,
237+
},
238+
}
239+
);
240+
241+
const afterData = await getAllCustomerInvoices();
242+
expect(afterData.value.length).to.equal(
243+
SECOND_CUSTOMER_INVOICES.value.length + 1
42244
);
43-
expect(data).to.eql(ALL_ALBUMS_WITH_TRACKS_BY_ARTIST);
44245
});
45246
});
46247
});

0 commit comments

Comments
 (0)