update tests

This commit is contained in:
Dmitriynj
2020-12-14 23:54:51 +03:00
committed by Daniel Hutzel
parent 145becb1c4
commit cb71e2ed9b
5 changed files with 340 additions and 48 deletions

View File

@@ -23,7 +23,7 @@
"scripts": { "scripts": {
"start": "npx cds run", "start": "npx cds run",
"deploy": "cds deploy --to sqlite:mychinook.db", "deploy": "cds deploy --to sqlite:mychinook.db",
"test": "mocha test/media-store.test.js --verbose --timeout 10000" "test": "npm run deploy && cd ../ && npm run jest"
}, },
"cds": { "cds": {
"ACCESS_TOKEN_SECRET": "secret", "ACCESS_TOKEN_SECRET": "secret",

View File

@@ -43,10 +43,12 @@ module.exports = async function () {
return Object.assign({}, userFromDb, { roles }); return Object.assign({}, userFromDb, { roles });
} }
/**
* User can only update and read his data
*/
this.before("UPDATE", "*", async (req) => { this.before("UPDATE", "*", async (req) => {
req.query = req.query.where({ ID: req.user.attr.ID }); req.query = req.query.where({ ID: req.user.attr.ID });
}); });
this.before("READ", "*", async (req) => { this.before("READ", "*", async (req) => {
req.query = req.query.where({ ID: req.user.attr.ID }); req.query = req.query.where({ ID: req.user.attr.ID });
}); });

View File

@@ -185,4 +185,89 @@ const ALL_ALBUMS_WITH_TRACKS_BY_ARTIST = {
], ],
}; };
module.exports = { FIRST_TRACK, ALL_ALBUMS_WITH_TRACKS_BY_ARTIST }; const SECOND_CUSTOMER = {
"@odata.context": "$metadata#Customers/$entity",
ID: 2,
lastName: "Köhler",
firstName: "Leonie",
city: "Stuttgart",
address: "Theodor-Heuss-Straße 34",
country: "Germany",
phone: "+49 0711 2842222",
email: "leonekohler@surfeu.de",
};
const FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER = {
"@odata.context": "$metadata#MarkedTracks/$entity",
ID: 4,
name: "Restless and Wild",
composer:
"F. Baltes, R.A. Smith-Diesel, S. Kaufman, U. Dirkscneider & W. Hoffman",
unitPrice: 0.99,
alreadyOrdered: true,
album_ID: 3,
genre_ID: 1,
};
const SECOND_CUSTOMER_INVOICES = {
"@odata.context": "$metadata#Invoices",
value: [
{
ID: 1,
invoiceDate: "2008-12-31T22:00:00Z",
total: 1.98,
status: 1,
customer_ID: 2,
},
{
ID: 12,
invoiceDate: "2009-02-10T22:00:00Z",
total: 13.86,
status: 1,
customer_ID: 2,
},
{
ID: 67,
invoiceDate: "2009-10-11T21:00:00Z",
total: 8.91,
status: 1,
customer_ID: 2,
},
{
ID: 196,
invoiceDate: "2011-05-18T21:00:00Z",
total: 1.98,
status: 1,
customer_ID: 2,
},
{
ID: 219,
invoiceDate: "2011-08-20T21:00:00Z",
total: 3.96,
status: 1,
customer_ID: 2,
},
{
ID: 241,
invoiceDate: "2011-11-22T21:00:00Z",
total: 5.94,
status: 1,
customer_ID: 2,
},
{
ID: 293,
invoiceDate: "2012-07-12T21:00:00Z",
total: 0.99,
status: 1,
customer_ID: 2,
},
],
};
module.exports = {
FIRST_TRACK,
ALL_ALBUMS_WITH_TRACKS_BY_ARTIST,
SECOND_CUSTOMER,
FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER,
SECOND_CUSTOMER_INVOICES,
};

View File

@@ -1,46 +1,247 @@
const { GET, POST, expect } = require("../../test").run("media-store"); const { GET, POST, expect } = require("../../test").run("media-store");
const cds = require("@sap/cds/lib"); const cds = require("@sap/cds/lib");
class MockedUser extends cds.User {
constructor(attr, roles, id) {
super({ attr, _roles: [...roles], id });
}
}
const { const {
FIRST_TRACK, FIRST_TRACK,
ALL_ALBUMS_WITH_TRACKS_BY_ARTIST, ALL_ALBUMS_WITH_TRACKS_BY_ARTIST,
SECOND_CUSTOMER,
FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER,
SECOND_CUSTOMER_INVOICES,
} = require("./data/media-store.mock"); } = require("./data/media-store.mock");
const fs = require("fs");
const DEFAULT_CONFIG = {
headers: { "content-type": "application/json" },
};
describe("Media Store services", () => { describe("Media Store services", () => {
before("skipping auth", () => { const CURRENT_CUSTOMER_DATA = {
cds.User = cds.User.Privileged; // skip auth ID: 2,
email: "leonekohler@surfeu.de",
password: "some",
roles: ["customer"],
};
const CURRENT_EMPLOYEE_DATA = {
ID: 4,
email: "margaret@chinookcorp.com",
password: "some",
roles: ["employee"],
};
let customerAccessToken;
let employeeAccessToken;
before("login user", async () => {
customerLoginResponse = await POST(
"/users/login",
{
email: CURRENT_CUSTOMER_DATA.email,
password: CURRENT_CUSTOMER_DATA.password,
},
DEFAULT_CONFIG
);
customerAccessToken = customerLoginResponse.data.accessToken;
employeeLoginResponse = await POST(
"/users/login",
{
email: CURRENT_EMPLOYEE_DATA.email,
password: CURRENT_EMPLOYEE_DATA.password,
},
DEFAULT_CONFIG
);
employeeAccessToken = employeeLoginResponse.data.accessToken;
}); });
it("should bootstrap the services successfully", () => { it("should bootstrap services successfully", () => {
const { BrowseTracks, db } = cds.services; const {
BrowseTracks,
BrowseInvoices,
ManageStore,
Users,
db,
} = cds.services;
const { Tracks } = BrowseTracks.entities; const { Tracks } = BrowseTracks.entities;
expect(BrowseTracks).not.to.be.undefined; expect(BrowseTracks).not.to.be.undefined;
expect(BrowseInvoices).not.to.be.undefined;
expect(ManageStore).not.to.be.undefined;
expect(Users).not.to.be.undefined;
expect(db).not.to.be.undefined; expect(db).not.to.be.undefined;
expect(Tracks).not.to.be.undefined; expect(Tracks).not.to.be.undefined;
}); });
describe("Tracks", () => { describe("Users", () => {
function compareAuthData(actualAuthData) {
expect(actualAuthData).not.to.be.undefined;
expect(actualAuthData).to.have.own.property("accessToken");
expect(actualAuthData).to.have.own.property("refreshToken");
expect(actualAuthData).to.have.own.property("ID");
expect(actualAuthData).to.have.own.property("email");
expect(actualAuthData).to.have.own.property("roles");
expect(actualAuthData.ID).to.equal(CURRENT_CUSTOMER_DATA.ID);
expect(actualAuthData.email).to.equal(CURRENT_CUSTOMER_DATA.email);
expect(actualAuthData.roles).to.deep.equal(CURRENT_CUSTOMER_DATA.roles);
}
it("should login user successfully", async () => {
const { data: actualData } = customerLoginResponse;
compareAuthData(actualData);
});
it("shouldn't login customer with invalid credentials", async () => {
try {
await POST(
"/users/login",
{
email: CURRENT_CUSTOMER_DATA.email,
password: "some-invalid-password",
},
DEFAULT_CONFIG
);
} catch (error) {
expect(error.message).to.equal("401 - Unauthorized");
}
});
it("should refresh tokens successfully", async () => {
const {
data: { refreshToken },
} = customerLoginResponse;
const { data: actualRefreshTokensData } = await POST(
"/users/refreshTokens",
{
refreshToken,
},
DEFAULT_CONFIG
);
compareAuthData(actualRefreshTokensData);
});
it("shouldn't refresh tokens due to invalid provided one", async () => {
try {
await POST(
"/users/refreshTokens",
{
refreshToken: "some-invalid-refresh-token",
},
DEFAULT_CONFIG
);
} catch (error) {
expect(error.message).to.equal("401 - Unauthorized");
}
});
it("current customer should retrieve his data", async () => {
const { data: actualData } = await GET(
`/users/Customers(${CURRENT_CUSTOMER_DATA.ID})`,
{
headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + customerAccessToken,
},
}
);
expect(actualData).not.to.be.undefined;
expect(actualData).to.deep.equal(SECOND_CUSTOMER);
});
it("current employee shouldn't have access to customer data", async () => {
const someCustomerID = 15;
try {
await GET(`/users/Customers(${someCustomerID})`, {
headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + employeeAccessToken,
},
});
} catch (error) {
expect(error.message).to.equal("403 - Forbidden");
}
});
it("current customer shouldn't retrieve his data without provided access token", async () => {
try {
await GET(`/users/Customers(11)`, DEFAULT_CONFIG);
} catch (error) {
expect(error.message).to.equal("401 - Unauthorized");
}
});
it("current customer shouldn't retrieve another customer data", async () => {
try {
await GET(`/users/Customers(11)`, {
headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + customerAccessToken,
},
});
} catch (error) {
expect(error.message).to.equal("404 - Not Found");
}
});
});
describe("BrowseTracks", () => {
it("should return track with ID eq 1", async () => { it("should return track with ID eq 1", async () => {
const { data } = await GET( const { data } = await GET(
"/browse-tracks/Tracks(1)?$expand=genre,album($expand=artist)" "/browse-tracks/Tracks(1)?$expand=genre,album($expand=artist)"
); );
expect(data).to.eql(FIRST_TRACK); expect(data).to.eql(FIRST_TRACK);
}); });
it("should return track with ID eq 4 for second customer", async () => {
const { data } = await GET("/browse-tracks/MarkedTracks(4)", {
headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + customerAccessToken,
},
});
expect(data).to.eql(FOURTH_MARKED_TRACK_FOR_SECOND_CUSTOMER);
});
}); });
describe("Albums", () => { describe("BrowseInvoices", () => {
it("should return all albums with tracks by artist", async () => { async function getAllCustomerInvoices() {
const { data } = await GET( const { data } = await GET("/browse-invoices/Invoices", {
`/browse-tracks/Albums?$filter=artist_ID eq 1&$expand=tracks` headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + customerAccessToken,
},
});
return data;
}
it("should return all invoices only for current customer", async () => {
const data = await getAllCustomerInvoices();
expect(data).to.eql(SECOND_CUSTOMER_INVOICES);
});
it("should create invoice for current customer", async () => {
const beforeData = await getAllCustomerInvoices();
expect(beforeData.value.length).to.equal(
SECOND_CUSTOMER_INVOICES.value.length
);
await POST(
"/browse-invoices/invoice",
{ tracks: [{ ID: 3 }] },
{
headers: {
...DEFAULT_CONFIG.headers,
authorization: "Basic " + customerAccessToken,
},
}
);
const afterData = await getAllCustomerInvoices();
expect(afterData.value.length).to.equal(
SECOND_CUSTOMER_INVOICES.value.length + 1
); );
expect(data).to.eql(ALL_ALBUMS_WITH_TRACKS_BY_ARTIST);
}); });
}); });
}); });

View File

@@ -4,29 +4,6 @@
@user-service = http://localhost:4004/users @user-service = http://localhost:4004/users
### ------------------------------------------------------------------------
## Browse Tracks service
### ------------------------------------------------------------------------
### ------------------------------------------------------------------------
# Get browse-tracks-service
GET {{browse-tracks-service}}
### ------------------------------------------------------------------------
# Get $metadata document of browse-tracks-service
GET {{browse-tracks-service}}/$metadata
### ------------------------------------------------------------------------
# Get Trakcs
GET {{browse-tracks-service}}/Tracks
### ------------------------------------------------------------------------
# Get Albums by artist ID axpanding tracks and artist
GET {{browse-tracks-service}}/Albums
?$filter=artist_ID eq 1
&$expand=tracks,artist
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
## Users service ## Users service
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
@@ -58,8 +35,8 @@ Content-Type: application/json
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Get current customer data # Get current customer data
GET {{user-service}}/Customers(2) GET {{user-service}}/Customers(1)
Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imxlb25la29obGVyQHN1cmZldS5kZSIsIklEIjoyLCJyb2xlcyI6WyJjdXN0b21lciJdLCJpYXQiOjE2MDc0MzE5NTgsImV4cCI6MTYwNzQzMjU1OH0.2sP3epaEo8tpBJZ-PuJInuC36TOyMgL2W6QjNFGyhSs Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imxlb25la29obGVyQHN1cmZldS5kZSIsIklEIjoyLCJyb2xlcyI6WyJjdXN0b21lciJdLCJpYXQiOjE2MDc5NTE2NDgsImV4cCI6MTYwNzk1MjI0OH0.4YqMxfY0KjOEA0iPvrZU5vfnsLcbFimxcamxgVxY4Ug
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Get current employee data # Get current employee data
@@ -74,8 +51,7 @@ Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFuZHJld0
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
# Get all current customer invoices # Get all current customer invoices
GET {{browse-invoices-service}}/Invoices GET {{browse-invoices-service}}/Invoices
Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imxlb25la29obGVyQHN1cmZldS5kZSIsIklEIjoyLCJyb2xlcyI6WyJjdXN0b21lciJdLCJpYXQiOjE2MDc0MzE5NTgsImV4cCI6MTYwNzQzMjU1OH0.2sP3epaEo8tpBJZ-PuJInuC36TOyMgL2W6QjNFGyhSs Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imxlb25la29obGVyQHN1cmZldS5kZSIsIklEIjoyLCJyb2xlcyI6WyJjdXN0b21lciJdLCJpYXQiOjE2MDc5Njg5ODIsImV4cCI6MTYwNzk2OTU4Mn0.Mq78megbpHa8ZyxhBPj7mwNs8Ttag6TeVekBKFDGR3w
### ------------------------------------------------------------------------ ### ------------------------------------------------------------------------
## Manage store service ## Manage store service
@@ -90,3 +66,31 @@ Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6ImFuZHJld0
{ {
"name": "some" "name": "some"
} }
### ------------------------------------------------------------------------
## Browse Tracks service
### ------------------------------------------------------------------------
### ------------------------------------------------------------------------
# Get browse-tracks-service
GET {{browse-tracks-service}}
### ------------------------------------------------------------------------
# Get $metadata document of browse-tracks-service
GET {{browse-tracks-service}}/$metadata
### ------------------------------------------------------------------------
# Get Trakcs
GET {{browse-tracks-service}}/Tracks
### ------------------------------------------------------------------------
# Get Albums by artist ID axpanding tracks and artist
GET {{browse-tracks-service}}/Albums
?$filter=artist_ID eq 1
&$expand=tracks,artist
### ------------------------------------------------------------------------
# Get Marked Trakcs
GET {{browse-tracks-service}}/MarkedTracks
Authorization: Basic eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imxlb25la29obGVyQHN1cmZldS5kZSIsIklEIjoyLCJyb2xlcyI6WyJjdXN0b21lciJdLCJpYXQiOjE2MDc5NjYxMTAsImV4cCI6MTYwNzk2NjcxMH0.VkxdhQth--kpxjb-X88N3H43kTtu5Uy0uVPsrQMx-ms