-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add personal data request handling - GDPR (#1214)
* landing page for GDPR data request confirmation REQUIRED ICM VERSION: 7.10.38.14-LTS Co-authored-by: Silke <s.grueber@intershop.de> Co-authored-by: Stefan Hauke <s.hauke@intershop.de>
- Loading branch information
1 parent
b2104e7
commit b8ba675
Showing
30 changed files
with
669 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,6 +18,7 @@ node_modules | |
/.nb-gradle | ||
/nbproject/ | ||
/.nvmrc | ||
/.vim/ | ||
|
||
# misc | ||
/.angular/cache | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/app/core/models/data-request/data-request.interface.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
/** | ||
* response data type for confirm data request | ||
*/ | ||
export interface DataRequestData { | ||
data: [ | ||
{ | ||
hash: string; | ||
} | ||
]; | ||
infos?: DataRequestInfo[]; | ||
} | ||
|
||
export interface DataRequestInfo { | ||
causes?: [ | ||
{ | ||
code: string; | ||
} | ||
]; | ||
} |
20 changes: 20 additions & 0 deletions
20
src/app/core/models/data-request/data-request.mapper.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { DataRequestData, DataRequestInfo } from './data-request.interface'; | ||
import { DataRequestMapper } from './data-request.mapper'; | ||
|
||
describe('Data Request Mapper', () => { | ||
describe('fromData', () => { | ||
it(`should return DataRequestConfirmation information when getting DataRequestData`, () => { | ||
const payloadData = { | ||
infos: [{ causes: [{ code: 'already confirmed' }] } as DataRequestInfo], | ||
} as DataRequestData; | ||
|
||
const dataRequest = DataRequestMapper.fromData(payloadData); | ||
|
||
expect(dataRequest).toMatchInlineSnapshot(` | ||
Object { | ||
"infoCode": "already confirmed", | ||
} | ||
`); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { DataRequestData } from './data-request.interface'; | ||
import { DataRequestConfirmation } from './data-request.model'; | ||
|
||
export class DataRequestMapper { | ||
/** | ||
* Map data request data to data request confirmation information | ||
*/ | ||
static fromData(data: DataRequestData): DataRequestConfirmation { | ||
return { | ||
infoCode: data?.infos[0]?.causes[0]?.code, | ||
}; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export interface DataRequest { | ||
requestID: string; | ||
hash: string; | ||
} | ||
|
||
export interface DataRequestConfirmation { | ||
infoCode: string; | ||
} |
61 changes: 61 additions & 0 deletions
61
src/app/core/services/data-requests/data-requests.service.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
import { TestBed } from '@angular/core/testing'; | ||
import { of } from 'rxjs'; | ||
import { anything, capture, instance, mock, verify, when } from 'ts-mockito'; | ||
|
||
import { DataRequestData, DataRequestInfo } from 'ish-core/models/data-request/data-request.interface'; | ||
import { DataRequest } from 'ish-core/models/data-request/data-request.model'; | ||
import { ApiService } from 'ish-core/services/api/api.service'; | ||
|
||
import { DataRequestsService } from './data-requests.service'; | ||
|
||
describe('Data Requests Service', () => { | ||
let apiServiceMock: ApiService; | ||
let dataRequestsService: DataRequestsService; | ||
|
||
beforeEach(() => { | ||
apiServiceMock = mock(ApiService); | ||
TestBed.configureTestingModule({ | ||
providers: [{ provide: ApiService, useFactory: () => instance(apiServiceMock) }], | ||
}); | ||
dataRequestsService = TestBed.inject(DataRequestsService); | ||
}); | ||
|
||
it('should be created', () => { | ||
expect(dataRequestsService).toBeTruthy(); | ||
}); | ||
|
||
describe('Confirm a data request', () => { | ||
it('should return an error when called with undefined', done => { | ||
when(apiServiceMock.put(anything(), anything())).thenReturn(of({})); | ||
|
||
dataRequestsService.confirmGDPRDataRequest(undefined).subscribe({ | ||
next: fail, | ||
error: err => { | ||
expect(err).toMatchInlineSnapshot(`[Error: confirmGDPRDataRequest() called without data body]`); | ||
done(); | ||
}, | ||
}); | ||
|
||
verify(apiServiceMock.put(anything(), anything())).never(); | ||
}); | ||
|
||
it("should confirm data request when 'confirmDataRequest' is called", done => { | ||
const requestData = { | ||
requestID: 'test_ID', | ||
hash: 'test_hash', | ||
} as DataRequest; | ||
const payloadData = { | ||
infos: [{ causes: [{ code: 'already confirmed' }] } as DataRequestInfo], | ||
} as DataRequestData; | ||
|
||
when(apiServiceMock.put(anything(), anything(), anything())).thenReturn(of(payloadData)); | ||
|
||
dataRequestsService.confirmGDPRDataRequest(requestData).subscribe(payload => { | ||
verify(apiServiceMock.put('gdpr-requests/test_ID/confirmations', anything(), anything())).once(); | ||
expect(capture(apiServiceMock.put).last()[0]).toMatchInlineSnapshot(`"gdpr-requests/test_ID/confirmations"`); | ||
expect(payload).toHaveProperty('infoCode', 'already confirmed'); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
37 changes: 37 additions & 0 deletions
37
src/app/core/services/data-requests/data-requests.service.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
import { HttpHeaders } from '@angular/common/http'; | ||
import { Injectable } from '@angular/core'; | ||
import { Observable, map, throwError } from 'rxjs'; | ||
|
||
import { DataRequestData } from 'ish-core/models/data-request/data-request.interface'; | ||
import { DataRequestMapper } from 'ish-core/models/data-request/data-request.mapper'; | ||
import { DataRequest, DataRequestConfirmation } from 'ish-core/models/data-request/data-request.model'; | ||
import { ApiService } from 'ish-core/services/api/api.service'; | ||
|
||
@Injectable({ providedIn: 'root' }) | ||
export class DataRequestsService { | ||
constructor(private apiService: ApiService) {} | ||
|
||
/** | ||
* Confirmation of a GDPR data request with corresponding request id and hash. | ||
* | ||
* @param data The DataRequest model includes request id and hash. | ||
* @returns The enriched DataRequest model includes additional response status and code of the request. | ||
*/ | ||
confirmGDPRDataRequest(data: DataRequest): Observable<DataRequestConfirmation> { | ||
if (!data) { | ||
return throwError(() => new Error('confirmGDPRDataRequest() called without data body')); | ||
} | ||
|
||
const dataRequestHeaderV1 = new HttpHeaders() | ||
.set('content-type', 'application/json') | ||
.set('Accept', 'application/vnd.intershop.gdpr.v1+json'); | ||
|
||
return this.apiService | ||
.put<DataRequestData>( | ||
`gdpr-requests/${data.requestID}/confirmations`, | ||
{ hash: data.hash }, | ||
{ headers: dataRequestHeaderV1 } | ||
) | ||
.pipe(map(payload => DataRequestMapper.fromData(payload))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
19 changes: 19 additions & 0 deletions
19
src/app/core/store/customer/data-requests/data-requests.actions.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { createAction } from '@ngrx/store'; | ||
|
||
import { DataRequest, DataRequestConfirmation } from 'ish-core/models/data-request/data-request.model'; | ||
import { httpError, payload } from 'ish-core/utils/ngrx-creators'; | ||
|
||
export const confirmGDPRDataRequest = createAction( | ||
'[DataRequest API] Confirm GDPR Data Request', | ||
payload<{ data: DataRequest }>() | ||
); | ||
|
||
export const confirmGDPRDataRequestSuccess = createAction( | ||
'[DataRequest API] Confirm GDPR Data Request Success', | ||
payload<DataRequestConfirmation>() | ||
); | ||
|
||
export const confirmGDPRDataRequestFail = createAction( | ||
'[DataRequest API] Confirm GDPR Data Request Failed', | ||
httpError() | ||
); |
Oops, something went wrong.