@@ -4,10 +4,13 @@ import sinon from 'sinon';
44import sinonChai from 'sinon-chai' ;
55import { CreateDataRequest , DataRequest , FlatDataRequestWithStatus , UpdateDataRequest } from '../models/data-request' ;
66import { DataRequestStatus , DataRequestStatusEnum } from '../models/data-request-status' ;
7+ import { PolicyEffect } from '../models/policy-statement' ;
78import { TeamMemberWithUser } from '../models/team-member' ;
89import { DataRequestRepository } from '../repositories/data-request-repository' ;
910import { getMockDBConnection } from '../__mocks__/db' ;
11+ import { PolicyService } from './access-policy/policy-service' ;
1012import { TeamMemberService } from './access-policy/team-member-service' ;
13+ import { TeamPolicyService } from './access-policy/team-policy-service' ;
1114import { TeamService } from './access-policy/team-service' ;
1215import { DataRequestService } from './data-request-service' ;
1316import { DataRequestStatusService } from './data-request-status-service' ;
@@ -197,62 +200,132 @@ describe('DataRequestService', () => {
197200 } ) ;
198201
199202 describe ( 'createDataRequest' , ( ) => {
200- it ( 'should create a data request with provided team_id and return it with status' , async ( ) => {
203+ const mockApprovedStatus : DataRequestStatus = {
204+ ...mockDataRequestStatus ,
205+ request_status : 'APPROVED'
206+ } ;
207+
208+ const mockPolicy = {
209+ policy_id : 'f6a7b8c9-d0e1-2345-fabc-456789012345' ,
210+ name : 'Data request policy - uuid' ,
211+ description : null ,
212+ statements : [ ]
213+ } ;
214+
215+ const mockTeamPolicy = {
216+ team_policy_id : '12345678-abcd-ef01-2345-678901234567' ,
217+ team_id : mockDataRequest . team_id ,
218+ policy_id : mockPolicy . policy_id
219+ } ;
220+
221+ const stubCreateDataRequestDependencies = (
222+ overrides : {
223+ teamId ?: string ;
224+ createNewTeam ?: boolean ;
225+ } = { }
226+ ) => {
227+ const { teamId = mockDataRequest . team_id , createNewTeam = false } = overrides ;
228+
229+ if ( createNewTeam ) {
230+ sinon
231+ . stub ( TeamService . prototype , 'createTeam' )
232+ . resolves ( { team_id : teamId , name : 'test' , description : null , member_count : 1 } ) ;
233+ sinon . stub ( TeamMemberService . prototype , 'createTeamMember' ) . resolves ( mockTeamMember ) ;
234+ }
235+
236+ sinon
237+ . stub ( DataRequestRepository . prototype , 'createDataRequest' )
238+ . resolves ( { ...mockDataRequest , team_id : teamId } ) ;
239+ sinon . stub ( PolicyService . prototype , 'createPolicyWithStatements' ) . resolves ( mockPolicy ) ;
240+ sinon . stub ( TeamPolicyService . prototype , 'createTeamPolicy' ) . resolves ( { ...mockTeamPolicy , team_id : teamId } ) ;
241+ sinon . stub ( DataRequestStatusService . prototype , 'createDataRequestStatus' ) . resolves ( mockApprovedStatus ) ;
242+ } ;
243+
244+ it ( 'should create a data request with provided team_id, create a policy, and auto-approve' , async ( ) => {
201245 const mockDB = getMockDBConnection ( ) ;
202246 const service = new DataRequestService ( mockDB ) ;
203247
204- const payload : CreateDataRequest = { reason : 'New research project' , team_id : mockDataRequest . team_id } ;
205- const createStub = sinon . stub ( DataRequestRepository . prototype , 'createDataRequest' ) . resolves ( mockDataRequest ) ;
206- const statusStub = sinon
207- . stub ( DataRequestStatusService . prototype , 'createDataRequestStatus' )
208- . resolves ( mockDataRequestStatus ) ;
248+ const payload : CreateDataRequest = {
249+ requested_by : mockDataRequest . requested_by ,
250+ reason : 'New research project' ,
251+ team_id : mockDataRequest . team_id
252+ } ;
253+
254+ stubCreateDataRequestDependencies ( ) ;
255+
256+ const createStub = DataRequestRepository . prototype . createDataRequest as sinon . SinonStub ;
257+ const policyStub = PolicyService . prototype . createPolicyWithStatements as sinon . SinonStub ;
258+ const teamPolicyStub = TeamPolicyService . prototype . createTeamPolicy as sinon . SinonStub ;
259+ const statusStub = DataRequestStatusService . prototype . createDataRequestStatus as sinon . SinonStub ;
260+
261+ const result = await service . createDataRequest ( payload ) ;
262+
263+ expect ( createStub ) . to . have . been . calledOnceWith ( mockDataRequest . requested_by , {
264+ ...payload ,
265+ team_id : mockDataRequest . team_id
266+ } ) ;
267+
268+ expect ( policyStub ) . to . have . been . calledOnce ;
269+ const policyArgs = policyStub . firstCall . args ;
270+ expect ( policyArgs [ 1 ] ) . to . deep . equal ( [ { effect : PolicyEffect . ALLOW , submission_feature_urn : 'urn:*:*:*' } ] ) ;
271+ expect ( policyArgs [ 0 ] ) . to . have . property ( 'record_end_date' ) . that . is . a ( 'string' ) ;
209272
210- const result = await service . createDataRequest ( mockDataRequest . requested_by , payload ) ;
273+ expect ( teamPolicyStub ) . to . have . been . calledOnceWith ( {
274+ team_id : mockDataRequest . team_id ,
275+ policy_id : mockPolicy . policy_id
276+ } ) ;
211277
212- expect ( createStub ) . to . have . been . calledOnceWith ( mockDataRequest . requested_by , payload ) ;
213278 expect ( statusStub ) . to . have . been . calledOnceWith (
214279 mockDataRequest . data_request_id ,
215- DataRequestStatusEnum . enum . REQUESTED ,
280+ DataRequestStatusEnum . enum . APPROVED ,
216281 undefined
217282 ) ;
283+
218284 expect ( result . data_request_id ) . to . equal ( mockDataRequest . data_request_id ) ;
219- expect ( result . data_request_status ) . to . deep . equal ( mockDataRequestStatus ) ;
285+ expect ( result . data_request_status . request_status ) . to . equal ( 'APPROVED' ) ;
220286 } ) ;
221287
222288 it ( 'should create a new team when payload.team_id is undefined' , async ( ) => {
223289 const mockDB = getMockDBConnection ( ) ;
224290 const service = new DataRequestService ( mockDB ) ;
225291
226292 const newTeamId = 'e5f6a7b8-c9d0-1234-efab-345678901234' ;
227- const teamStub = sinon
228- . stub ( TeamService . prototype , 'createTeam' )
229- . resolves ( { team_id : newTeamId , name : 'test' , description : null , member_count : 0 } ) ;
230- const memberStub = sinon . stub ( TeamMemberService . prototype , 'createTeamMember' ) . resolves ( mockTeamMember ) ;
231- sinon . stub ( DataRequestRepository . prototype , 'createDataRequest' ) . resolves ( {
232- ...mockDataRequest ,
233- team_id : newTeamId
234- } ) ;
235- sinon . stub ( DataRequestStatusService . prototype , 'createDataRequestStatus' ) . resolves ( mockDataRequestStatus ) ;
293+ stubCreateDataRequestDependencies ( { teamId : newTeamId , createNewTeam : true } ) ;
236294
237- const payload : CreateDataRequest = { reason : 'New research project' } ;
238- await service . createDataRequest ( mockDataRequest . requested_by , payload ) ;
295+ const teamStub = TeamService . prototype . createTeam as sinon . SinonStub ;
296+ const memberStub = TeamMemberService . prototype . createTeamMember as sinon . SinonStub ;
297+ const teamPolicyStub = TeamPolicyService . prototype . createTeamPolicy as sinon . SinonStub ;
298+
299+ const payload : CreateDataRequest = {
300+ requested_by : mockDataRequest . requested_by ,
301+ reason : 'New research project'
302+ } ;
303+ await service . createDataRequest ( payload ) ;
239304
240305 expect ( teamStub ) . to . have . been . calledOnce ;
241306 expect ( memberStub ) . to . have . been . calledOnceWith ( {
242307 system_user_id : mockDataRequest . requested_by ,
243308 team_id : newTeamId
244309 } ) ;
310+ expect ( teamPolicyStub ) . to . have . been . calledOnceWith ( {
311+ team_id : newTeamId ,
312+ policy_id : mockPolicy . policy_id
313+ } ) ;
245314 } ) ;
246315
247316 it ( 'should propagate repository errors' , async ( ) => {
248317 const mockDB = getMockDBConnection ( ) ;
249318 const service = new DataRequestService ( mockDB ) ;
250319
251- const payload : CreateDataRequest = { reason : 'Test' , team_id : mockDataRequest . team_id } ;
320+ const payload : CreateDataRequest = {
321+ requested_by : 1 ,
322+ reason : 'Test' ,
323+ team_id : mockDataRequest . team_id
324+ } ;
252325 sinon . stub ( DataRequestRepository . prototype , 'createDataRequest' ) . rejects ( new Error ( 'DB error' ) ) ;
253326
254327 try {
255- await service . createDataRequest ( 1 , payload ) ;
328+ await service . createDataRequest ( payload ) ;
256329 throw new Error ( 'Expected to throw' ) ;
257330 } catch ( err ) {
258331 expect ( err ) . to . be . instanceOf ( Error ) ;
0 commit comments