@@ -205,6 +205,100 @@ export function testRecordsReadHandler(): void {
205205 expect ( ArrayUtility . byteArraysEqual ( dataFetched , dataBytes ! ) ) . to . be . true ;
206206 } ) ;
207207
208+ it ( 'should return 400 when fetching initial write for a deleted record fails' , async ( ) => {
209+ const alice = await TestDataGenerator . generateDidKeyPersona ( ) ;
210+
211+ // Write a record
212+ const { message : writeMessage , dataStream } = await TestDataGenerator . generateRecordsWrite ( { author : alice } ) ;
213+ const writeReply = await dwn . processMessage ( alice . did , writeMessage , { dataStream } ) ;
214+ expect ( writeReply . status . code ) . to . equal ( 202 ) ;
215+
216+ // Delete the record
217+ const recordsDelete = await RecordsDelete . create ( {
218+ signer : Jws . createSigner ( alice ) ,
219+ recordId : writeMessage . recordId
220+ } ) ;
221+ const deleteReply = await dwn . processMessage ( alice . did , recordsDelete . message ) ;
222+ expect ( deleteReply . status . code ) . to . equal ( 202 ) ;
223+
224+ // Stub the messageStore.query method to simulate failure in fetching initial write
225+ const queryStub = sinon . stub ( dwn [ 'messageStore' ] , 'query' ) ;
226+ queryStub . onFirstCall ( ) . resolves ( { messages : [ recordsDelete . message ] } ) ;
227+ queryStub . onSecondCall ( ) . resolves ( { messages : [ ] } ) ; // Simulate no initial write found
228+
229+ // Attempt to read the deleted record
230+ const recordsRead = await RecordsRead . create ( {
231+ filter : { recordId : writeMessage . recordId } ,
232+ signer : Jws . createSigner ( alice )
233+ } ) ;
234+ const readReply = await dwn . processMessage ( alice . did , recordsRead . message ) ;
235+
236+ // Verify the response
237+ expect ( readReply . status . code ) . to . equal ( 400 ) ;
238+ expect ( readReply . status . detail ) . to . contain ( DwnErrorCode . RecordsReadInitialWriteNotFound ) ;
239+
240+ // Restore the original messageStore.query method
241+ queryStub . restore ( ) ;
242+ } ) ;
243+
244+ it ( 'should return 401 when a non-author attempts to read the initial write of a deleted record' , async ( ) => {
245+ const alice = await TestDataGenerator . generateDidKeyPersona ( ) ;
246+ const bob = await TestDataGenerator . generateDidKeyPersona ( ) ;
247+ const carol = await TestDataGenerator . generateDidKeyPersona ( ) ;
248+
249+ // Alice installs a protocol that allows anyone to write
250+ const protocolDefinition : ProtocolDefinition = {
251+ published : true ,
252+ protocol : 'https://example.com/foo' ,
253+ types : {
254+ foo : { }
255+ } ,
256+ structure : {
257+ foo : {
258+ $actions : [ {
259+ who : 'anyone' ,
260+ can : [ 'create' , 'delete' ]
261+ } ]
262+ }
263+ }
264+ } ;
265+
266+ const configureProtocol = await TestDataGenerator . generateProtocolsConfigure ( {
267+ author : alice ,
268+ protocolDefinition : protocolDefinition ,
269+ } ) ;
270+ const configureProtocolReply = await dwn . processMessage ( alice . did , configureProtocol . message ) ;
271+ expect ( configureProtocolReply . status . code ) . to . equal ( 202 ) ;
272+
273+ // Bob writes a record to Alice's DWN
274+ const { message : writeMessage , dataStream } = await TestDataGenerator . generateRecordsWrite ( {
275+ author : bob ,
276+ protocol : protocolDefinition . protocol ,
277+ protocolPath : 'foo'
278+ } ) ;
279+ const writeReply = await dwn . processMessage ( alice . did , writeMessage , { dataStream } ) ;
280+ expect ( writeReply . status . code ) . to . equal ( 202 ) ;
281+
282+ // Bob deletes the record
283+ const recordsDelete = await RecordsDelete . create ( {
284+ signer : Jws . createSigner ( bob ) ,
285+ recordId : writeMessage . recordId
286+ } ) ;
287+ const deleteReply = await dwn . processMessage ( alice . did , recordsDelete . message ) ;
288+ expect ( deleteReply . status . code ) . to . equal ( 202 ) ;
289+
290+ // Carol attempts to read the deleted record
291+ const recordsRead = await RecordsRead . create ( {
292+ filter : { recordId : writeMessage . recordId } ,
293+ signer : Jws . createSigner ( carol )
294+ } ) ;
295+ const readReply = await dwn . processMessage ( alice . did , recordsRead . message ) ;
296+
297+ // Verify the response
298+ expect ( readReply . status . code ) . to . equal ( 401 ) ;
299+ expect ( readReply . status . detail ) . to . contain ( DwnErrorCode . ProtocolAuthorizationActionNotAllowed ) ;
300+ } ) ;
301+
208302 it ( 'should allow a non-tenant to read RecordsRead data they have authored' , async ( ) => {
209303 const alice = await TestDataGenerator . generateDidKeyPersona ( ) ;
210304 const bob = await TestDataGenerator . generateDidKeyPersona ( ) ;
0 commit comments