Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tests #101

Merged
merged 5 commits into from
Sep 9, 2024
Merged

Tests #101

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ jobs:
run: |
npm install
npm run lint
npm run test

- name: get-version
id: package-version
Expand Down
27 changes: 27 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
name: CI

on:
workflow_dispatch:
push:
branches: [ main ]
pull_request:
branches: [ main ]

jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [20.x, 18.x]
steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- run: npm i -g @sap/cds-dk
- run: npm i
- run: cd tests/incidents-app && npm i
- run: cds v
- run: npm run test
2 changes: 1 addition & 1 deletion lib/basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ module.exports = class AttachmentsService extends cds.Service {

async getStatus(Attachments, key) {
const result = await SELECT.from(Attachments, key).columns('status')
return result.status
return result?.status;
}

async deleteInfectedAttachment(Attachments, key) {
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
"srv"
],
"scripts": {
"lint": "npx eslint ."
"lint": "npx eslint .",
"test": "npx jest attachments.test.js"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.400.0",
Expand Down
7 changes: 7 additions & 0 deletions tests/incidents-app/db/attachments.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@

using { sap.capire.incidents as my } from './schema';
using { Attachments } from '@cap-js/attachments';

extend my.Incidents with {
attachments: Composition of many Attachments;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ID,customer_ID,city,postCode,streetAddress
17e00347-dc7e-4ca9-9c5d-06ccef69f064,1004155,Rome,00164,Piazza Adriana
d8e797d9-6507-4aaa-b43f-5d2301df5135,1004161,Munich,80809,Olympia Park
ff13d2fa-e00f-4ee5-951c-3303f490777b,1004100,Walldorf,69190,Dietmar-Hopp-Allee
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ID,firstName,lastName,email,phone
1004155,Daniel,Watts,[email protected],+44-555-123
1004161,Stormy,Weathers,[email protected],
1004100,Sunny,Sunshine,[email protected],+01-555-789
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ID,up__ID,timestamp,author,message
2b23bb4b-4ac7-4a24-ac02-aa10cabd842c,3b23bb4b-4ac7-4a24-ac02-aa10cabd842c,1995-12-17T03:24:00Z,Harry John,Can you please check if battery connections are fine?
2b23bb4b-4ac7-4a24-ac02-aa10cabd843c,3a4ede72-244a-4f5f-8efa-b17e032d01ee,1995-12-18T04:24:00Z,Emily Elizabeth,Can you please check if there are any loose connections?
9583f982-d7df-4aad-ab26-301d4a157cd7,3583f982-d7df-4aad-ab26-301d4a157cd7,2022-09-04T12:00:00Z,Sunny Sunshine,Please check why the solar panel is broken
9583f982-d7df-4aad-ab26-301d4a158cd7,3ccf474c-3881-44b7-99fb-59a2a4668418,2022-09-04T13:00:00Z,Bradley Flowers,What exactly is wrong?
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
ID,customer_ID,title,urgency_code,status_code
3b23bb4b-4ac7-4a24-ac02-aa10cabd842c,1004155,Inverter not functional,H,C
3a4ede72-244a-4f5f-8efa-b17e032d01ee,1004161,No current on a sunny day,H,N
3ccf474c-3881-44b7-99fb-59a2a4668418,1004161,Strange noise when switching off Inverter,M,N
3583f982-d7df-4aad-ab26-301d4a157cd7,1004100,Solar panel broken,H,I
7 changes: 7 additions & 0 deletions tests/incidents-app/db/data/sap.capire.incidents-Status.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
code;descr;criticality
N;New;3
A;Assigned;2
I;In Process;2
H;On Hold;3
R;Resolved;2
C;Closed;4
4 changes: 4 additions & 0 deletions tests/incidents-app/db/data/sap.capire.incidents-Urgency.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
code;descr
H;High
M;Medium
L;Low
66 changes: 66 additions & 0 deletions tests/incidents-app/db/schema.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using { cuid, managed, sap.common.CodeList } from '@sap/cds/common';

namespace sap.capire.incidents;

/**
* Customers using products sold by our company.
* Customers can create support Incidents.
*/
entity Customers : managed {
key ID : String;
firstName : String;
lastName : String;
name : String = firstName ||' '|| lastName;
email : EMailAddress;
phone : PhoneNumber;
creditCardNo : String(16) @assert.format: '^[1-9]\d{15}$';
addresses : Composition of many Addresses on addresses.customer = $self;
incidents : Association to many Incidents on incidents.customer = $self;
}

entity Addresses : cuid, managed {
customer : Association to Customers;
city : String;
postCode : String;
streetAddress : String;
}


/**
* Incidents created by Customers.
*/
entity Incidents : cuid, managed {
customer : Association to Customers;
title : String @title: 'Title';
urgency : Association to Urgency default 'M';
status : Association to Status default 'N';
conversation : Composition of many {
key ID : UUID;
timestamp : type of managed:createdAt;
author : type of managed:createdBy;
message : String;
};
}

entity Status : CodeList {
key code : String enum {
new = 'N';
assigned = 'A';
in_process = 'I';
on_hold = 'H';
resolved = 'R';
closed = 'C';
};
criticality : Integer;
}

entity Urgency : CodeList {
key code : String enum {
high = 'H';
medium = 'M';
low = 'L';
};
}

type EMailAddress : String;
type PhoneNumber : String;
33 changes: 33 additions & 0 deletions tests/incidents-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "@capire/incidents",
"version": "1.0.0",
"dependencies": {
"@cap-js/attachments": "file:../../."
},
"cds": {
"requires": {
"auth": {
"[development]": {
"users": {
"alice": {
"roles": [
"support",
"admin"
]
},
"bob": {
"roles": [
"support"
]
}
}
}
},
"attachments": {
"kind": "db",
"scan": false
}
}
},
"private": true
}
21 changes: 21 additions & 0 deletions tests/incidents-app/srv/services.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using { sap.capire.incidents as my } from '../db/schema';

/**
* Service used by support personell, i.e. the incidents' 'processors'.
*/
service ProcessorService {
entity Incidents as projection on my.Incidents;
entity Customers @readonly as projection on my.Customers;
}

/**
* Service used by administrators to manage customers and incidents.
*/
service AdminService {
entity Customers as projection on my.Customers;
entity Incidents as projection on my.Incidents;
}

annotate ProcessorService.Incidents with @odata.draft.enabled;
annotate ProcessorService with @(requires: 'support');
annotate AdminService with @(requires: 'admin');
32 changes: 32 additions & 0 deletions tests/incidents-app/srv/services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
const cds = require('@sap/cds')
const { SELECT } = cds.ql

class ProcessorService extends cds.ApplicationService {
/** Registering custom event handlers */
init() {
this.before('UPDATE', 'Incidents', req => this.onUpdate(req))
this.before(['CREATE', 'UPDATE'], 'Incidents', req => this.changeUrgencyDueToSubject(req.data))
return super.init()
}

changeUrgencyDueToSubject(data) {
if (data) {
const incidents = Array.isArray(data) ? data : [data]
incidents.forEach(incident => {
if (incident.title?.toLowerCase().includes('urgent')) {
incident.urgency = { code: 'H', descr: 'High' }
}
})
}
}

/** Custom Validation */
async onUpdate(req) {
const { status_code } = await SELECT.one(req.subject, i => i.status_code).where({ ID: req.data.ID })
if (status_code === 'C') {
return req.reject(`Can't modify a closed incident`)
}
}
}

module.exports = { ProcessorService }
75 changes: 26 additions & 49 deletions tests/integration/attachments.test.js
Original file line number Diff line number Diff line change
@@ -1,61 +1,29 @@
const cds = require("@sap/cds");
const incidentsApp = require("path").resolve(__dirname, "./../../xmpl");
const { expect, axios, GET, POST, DELETE } = cds.test(incidentsApp);
const path = require("path");
const app = path.resolve(__dirname, "../incidents-app");
const { expect, axios, GET, POST, DELETE } = cds.test(app);
const { RequestSend } = require("../utils/api");
const { createReadStream } = cds.utils.fs;
const { join } = cds.utils.path;

axios.defaults.auth = { username: "alice" };
jest.setTimeout(5 * 60 * 1000);

const utils = new RequestSend(POST);
let utils = null;
let sampleDocID = null;
let incidentID = null;

describe("Tests for mock data in xmpl attachments - in-memory db", () => {
beforeAll(() => {
sampleDocID = null;
incidentID = "3b23bb4b-4ac7-4a24-ac02-aa10cabd842c";
});

//Reading the attachment list and checking for content
it("Reading attachments list", async () => {
//read attachments list for Incident - Inverter not functional
try {
const response = await GET(
`odata/v4/processor/Incidents(ID=${incidentID},IsActiveEntity=true)/attachments`
);
//the mock data has two attachments in this incident
expect(response.status).to.equal(200);
expect(response.data.value.length).to.equal(2);
sampleDocID = response.data.value[0].ID;
//to make sure content is not read
expect(response.data.value[0].content).to.be.undefined;
} catch (err) {
expect(err).to.be.undefined;
}
});

//Reading the uploaded attachment content and that it exists
it("Reading the uploaded attachment document", async () => {
//checking the uploaded attachment document

try {
const response = await GET(
`odata/v4/processor/Incidents(ID=${incidentID},IsActiveEntity=true)/attachments(up__ID=${incidentID},ID=${sampleDocID},IsActiveEntity=true)/content`
);
expect(response.status).to.equal(200);
expect(response.data).to.not.be.undefined;
} catch (err) {
expect(err).to.be.undefined;
}
});
});
let db = null;

Check warning on line 15 in tests/integration/attachments.test.js

View workflow job for this annotation

GitHub Actions / lint

'db' is assigned a value but never used
let attachmentsService = null;

Check warning on line 16 in tests/integration/attachments.test.js

View workflow job for this annotation

GitHub Actions / lint

'attachmentsService' is assigned a value but never used

describe("Tests for uploading/deleting attachments through API calls - in-memory db", () => {
beforeAll(async () => {
cds.env.requires.db.kind = "sql";
cds.env.requires.attachments.kind = "db";
db = await cds.connect.to("sql:my.db");
attachmentsService = await cds.connect.to("attachments");
sampleDocID = null;
incidentID = "3ccf474c-3881-44b7-99fb-59a2a4668418";
utils = new RequestSend(POST);
});

//Draft mode uploading attachment
Expand Down Expand Up @@ -94,15 +62,12 @@
const response = await GET(
`odata/v4/processor/Incidents(ID=${incidentID},IsActiveEntity=true)/attachments`
);
//the data should have two attachments
//the data should have only one attachment
expect(response.status).to.equal(200);
expect(response.data.value.length).to.equal(2);
expect(response.data.value.length).to.equal(1);
//to make sure content is not read
expect(response.data.value[0].content).to.be.undefined;
sampleDocID =
response.data.value[0].filename == "sample.pdf"
? response.data.value[0].ID
: response.data.value[1].ID;
sampleDocID = response.data.value[0].ID;
} catch (err) {
expect(err).to.be.undefined;
}
Expand Down Expand Up @@ -149,9 +114,21 @@
expect(err).to.be.undefined;
}

//read attachments list for Incident
try {
const response = await GET(
`odata/v4/processor/Incidents(ID=${incidentID},IsActiveEntity=true)/attachments`
);
//the data should have no attachments
expect(response.status).to.equal(200);
expect(response.data.value.length).to.equal(0);
} catch (err) {
expect(err).to.be.undefined;
}

//content should not be there
try {
const response = await GET(

Check warning on line 131 in tests/integration/attachments.test.js

View workflow job for this annotation

GitHub Actions / lint

'response' is assigned a value but never used
`odata/v4/processor/Incidents(ID=${incidentID},IsActiveEntity=true)/attachments(up__ID=${incidentID},ID=${sampleDocID},IsActiveEntity=true)/content`
);
} catch (err) {
Expand Down
Loading