Skip to content

Commit

Permalink
Test to reproduce issue
Browse files Browse the repository at this point in the history
  • Loading branch information
schiwekM committed Dec 12, 2024
1 parent 1233b58 commit 2692475
Show file tree
Hide file tree
Showing 12 changed files with 494 additions and 0 deletions.
55 changes: 55 additions & 0 deletions test/personal-data-complex/crud.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
const cds = require('@sap/cds')

const { POST: _POST, PATCH: _PATCH, GET: _GET, DELETE: _DELETE, data } = cds.test().in(__dirname)

// the persistent outbox adds a delay
const wait = require('util').promisify(setTimeout)
const DELAY = process.env.CI ? 42 : 7
const POST = (...args) => _POST(...args).then(async res => (await wait(DELAY), res))
const PATCH = (...args) => _PATCH(...args).then(async res => (await wait(DELAY), res))
const GET = (...args) => _GET(...args).then(async res => (await wait(DELAY), res))
const DELETE = (...args) => _DELETE(...args).then(async res => (await wait(DELAY), res))

// TODO: @cap-js/sqlite doesn't support structured properties
// // needed for testing structured properties
// cds.env.odata.flavor = 'x4'

const _logger = require('../utils/logger')({ debug: true })
cds.log.Logger = _logger

describe('personal data audit logging in CRUD with complex model', () => {
let __log, _logs
const _log = (...args) => {
if (!(args.length === 2 && typeof args[0] === 'string' && args[0].match(/\[audit-log\]/i))) {
// > not an audit log (most likely, anyway)
return __log(...args)
}

_logs.push(args[1])
}

const ALICE = { username: 'alice', password: 'password' }

beforeAll(() => {
__log = global.console.log
global.console.log = _log
})

afterAll(() => {
global.console.log = __log
})

beforeEach(async () => {
await data.reset()
_logs = []
_logger._resetLogs()
})

describe('data deletion logging', () => {
test('Delete PII record in action', async () => {
const { status: statusLeave } = await POST('/collaborations/Collaborations(ID=36ca041a-a337-4d08-8099-c2a0980823a0,IsActiveEntity=true)/CollaborationsService.leave', {}, {auth: ALICE})
expect(statusLeave).toEqual(204);
});

})
})
192 changes: 192 additions & 0 deletions test/personal-data-complex/db/collaborations.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
using {
cuid,
managed
} from '@sap/cds/common';

using {
sap.taco.core.Students,
sap.hcm.Employees
} from './schema';

namespace sap.taco.collaborations;

entity Collaborations : cuid, managed {
title : String(100);
participants : Composition of many Participants
on participants.collaboration = $self;
applications : Composition of many Applications
on applications.collaboration = $self;
subCollaborations : Composition of many SubCollaborations
on subCollaborations.collaboration = $self;
leadAssignments : Composition of many CollaborationLeadAssignments
on leadAssignments.collaboration = $self;
collaborationLogs : Association to many CollaborationLogs
on collaborationLogs.collaboration = $self;
leads = participants[validFrom <= $now
and validTo >= $now
and isLead = true];
activeParticipants = participants[validFrom <= $now
and validTo >= $now];
}

@assert.unique: {onlyOne: [
collaboration,
student
], }
entity Participants : cuid {
collaboration : Association to one Collaborations;
student : Association to one Students;
employeeNav : Association to one Employees
on employeeNav.userID = student.userID;
validFrom : Date;
validTo : Date;
isLead : Boolean default false;
leadAssignment : Association to one CollaborationLeadAssignments
on leadAssignment.collaboration = collaboration
and leadAssignment.student = student;
subCollaborations : Composition of many SubCollaborationAssignments
on subCollaborations.participant = $self;
collaborationLogs : Association to many CollaborationLogs
on collaborationLogs.collaboration_ID = collaboration.ID
and student.userID = collaborationLogs.userID;
}

@assert.unique: {onlyOne: [
collaboration,
student
], }
entity CollaborationLeadAssignments : cuid {
collaboration : Association to one Collaborations;
student : Association to one Students;
employeeNav : Association to one Employees
on employeeNav.userID = student.userID;
validFrom : Date;
validTo : Date;
}

@assert.unique: {onlyOne: [
collaboration,
student
], }
entity Applications : cuid {
collaboration : Association to one Collaborations;
student : Association to one Students;
employeeNav : Association to one Employees
on employeeNav.userID = student.userID;
application : String(1000);
subCollaborationApplications : Composition of many SubCollaborationApplications
on subCollaborationApplications.application = $self;
}

@assert.unique: {onlyOne: [
subCollaboration,
application
], }
entity SubCollaborationApplications : cuid {
subCollaboration : Association to one SubCollaborations;
application : Association to one Applications;
leads : Association to many SubCollaborationLeads
on leads.subCollaboration_ID = subCollaboration.ID;
}

entity SubCollaborations : cuid {
collaboration : Association to one Collaborations;
title : String(100);
participants : Association to many SubCollaborationAssignments
on participants.subCollaboration = $self @odata.draft.enclosed;
activeParticipants : Association to many ActiveSubCollaborationAssignments
on activeParticipants.subCollaboration = $self;
leads : Association to many SubCollaborationLeads
on leads.subCollaboration = $self /* and leads.isLead = true */;
}

entity ActiveSubCollaborationAssignments as
select from SubCollaborationAssignments {
*,
participant.student.userID as student_userID @UI.Hidden,
}
where
validFrom <= $now
and validTo >= $now;

entity SubCollaborationsVH as select from SubCollaborations;

annotate SubCollaborationsVH with {
ID @UI.Hidden: false @Common.Text: title @Common.TextArrangement: #TextOnly
}

@assert.unique: {onlyOne: [
subCollaboration_ID,
participant
], }
entity SubCollaborationAssignments : cuid {
subCollaboration_ID : UUID;
subCollaboration : Association to one SubCollaborations
on subCollaboration.ID = subCollaboration_ID;
participant : Association to one Participants;
isLead : Boolean default false;
validFrom : Date;
validTo : Date;
}

//REVISIT: Once isLead = true works also in associations and within exists navigations can be used
@readonly
entity SubCollaborationLeads as
projection on SubCollaborationAssignments {
*,
participant.student.userID as student_userID @readonly
}
where
isLead = true
and validFrom <= $now
and validTo >= $now;

annotate SubCollaborationLeads with {
participant @readonly;
}

entity CollaborationLogs : cuid {
userID : String;
student : Association to one Students
on student.userID = userID;
collaboration_ID : UUID;
collaboration : Association to one Collaborations
on collaboration.ID = collaboration_ID;
participant : Association to one Participants
on participant.student.userID = userID
and participant.collaboration.ID = collaboration_ID;
title : String(100);
approver : Association to one Employees;
}

annotate Collaborations {
endDate @PersonalData.FieldSemantics: 'EndOfBusinessDate';
}

annotate Applications with @PersonalData : {
DataSubjectRole : 'Student',
EntitySemantics : 'Other'
} {
student @PersonalData.FieldSemantics: 'DataSubjectID';
application @PersonalData.IsPotentiallyPersonal;
}

annotate CollaborationLeadAssignments with @PersonalData : {
DataSubjectRole : 'Student',
EntitySemantics : 'Other'
} {
student @PersonalData.FieldSemantics: 'DataSubjectID';
}

annotate Participants with @PersonalData: {
DataSubjectRole: 'Student',
EntitySemantics: 'Other'
} {
student @PersonalData.FieldSemantics: 'DataSubjectID';
validTo @PersonalData.FieldSemantics: 'EndOfBusinessDate';
}

annotate CollaborationLogs with {
userID @PersonalData.FieldSemantics: 'DataSubjectID';
approver @PersonalData.FieldSemantics: 'UserID';
}
3 changes: 3 additions & 0 deletions test/personal-data-complex/db/data/sap.hcm-Employees.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
userID;displayName;firstName;lastName;initials;email;mobilePhone;officePhone;manager_userID
alice;Alice;Alice;;A;[email protected];123;456;I123456
I123456;Bettina;Bettina;;B;[email protected];789;101112;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID;title
36ca041a-a337-4d08-8099-c2a0980823a0;Test 1
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID;collaboration_ID;student_userID;isLead;validFrom;validTo
eea721d7-01cb-4862-a5fc-6e35cc55dd8f;36ca041a-a337-4d08-8099-c2a0980823a0;alice;true;2020-09-01;2023-09-30
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID;subCollaboration_ID;participant_ID;validFrom;validTo;isLead
9ced9799-d482-4f02-91ea-69457bc01d48;3913541a-5419-429c-b476-ed07ae8ed3b0;eea721d7-01cb-4862-a5fc-6e35cc55dd8f;2020-09-01;2023-09-30;false
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ID;collaboration_ID;title
3913541a-5419-429c-b476-ed07ae8ed3b0;36ca041a-a337-4d08-8099-c2a0980823a0;Test 1 subcollab
2 changes: 2 additions & 0 deletions test/personal-data-complex/db/data/sap.taco.core-Students.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
userID;trainingHours;sumCompletedCollaborationLogs;validTo
alice;0;0;2023-09-30
98 changes: 98 additions & 0 deletions test/personal-data-complex/db/schema.cds
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using {
cuid,
managed
} from '@sap/cds/common';

using {
sap.taco.collaborations.CollaborationLogs,
sap.taco.collaborations.CollaborationLeadAssignments,
sap.taco.collaborations.Participants,
sap.taco.collaborations.Applications,
} from './schema';

extend managed with {
createdByNav : Association to one sap.hcm.Employees on createdByNav.userID = createdBy;
modifiedByNav : Association to one sap.hcm.Employees on modifiedByNav.userID = modifiedBy;
};

context sap.hcm {
entity Employees {
key userID: String;
displayName: String;
firstName: String;
lastName: String;
initials: String;
email: String;
mobilePhone: String;
officePhone: String;
manager_userID: String;
}

annotate Employees with @PersonalData : {
DataSubjectRole : 'Employee',
EntitySemantics : 'DataSubject',
} {
userID @PersonalData.FieldSemantics : 'DataSubjectID';
displayName @PersonalData.IsPotentiallyPersonal;
firstName @PersonalData.IsPotentiallyPersonal;
lastName @PersonalData.IsPotentiallyPersonal;
initials @PersonalData.IsPotentiallyPersonal;
email @PersonalData.IsPotentiallyPersonal;
mobilePhone @PersonalData.IsPotentiallyPersonal;
officePhone @PersonalData.IsPotentiallyPersonal;
manager_userID @PersonalData.FieldSemantics : 'UserID'
};
}

context sap.taco.core {
entity Events : cuid, managed {
referenceID : UUID @UI.readonly;
students : Composition of many EventStudentAssignments
on students.event = $self;
title : String;
type_code : String;
collaborationLog : Association to one CollaborationLogs
on collaborationLog.ID = referenceID;
}

entity EventStudentAssignments : cuid {
event : Association to one Events;
student : Association to one Students;
}

entity Students {
key userID: String;
validTo: Date;
employeeNav : Association to one sap.hcm.Employees on employeeNav.userID = userID;
trainingHours: Decimal;
sumCompletedCollaborationLogs: Integer;
collaborations : Composition of many CollaborationLogs
on collaborations.userID = userID @UI.ExcludeFromNavigationContext;
collaborationApplications : Composition of many Applications
on collaborationApplications.student = $self;
leadAssignments : Composition of many CollaborationLeadAssignments
on leadAssignments.student = $self;
collaborationAssignments : Composition of many Participants
on collaborationAssignments.student = $self;
eventAssignments : Composition of many EventStudentAssignments
on eventAssignments.student = $self;
}

annotate Events with {
createdBy @PersonalData.FieldSemantics: 'UserID';
modifiedBy @PersonalData.FieldSemantics: 'UserID';
}

annotate EventStudentAssignments with {
student @PersonalData.FieldSemantics: 'DataSubjectID';
}

annotate Students with @PersonalData: {
DataSubjectRole: 'Student',
EntitySemantics: 'DataSubject',
} {
userID @PersonalData.FieldSemantics: 'DataSubjectID';
trainingHours @PersonalData.IsPotentiallyPersonal;
openTasks @PersonalData.IsPotentiallyPersonal;
}
}
5 changes: 5 additions & 0 deletions test/personal-data-complex/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@cap-js/audit-logging": "*"
}
}
Loading

0 comments on commit 2692475

Please sign in to comment.