2

I want to intercept a rpc call that I made to the api in my react app. I'm using a custom hook that receives the buffer and the rpc method that I want to call and returns the data(something like react-query useQuery hook).

The thing is because of being a rpc call, the request urls of my requests are all the same and the response is binary, I can't distinguish the requests and intercept the one to stub.

One example of making a rpc call:

const {response, loading, error} = useRpc({
   Buffer: GetUser,
   Request: GetUserRequest
});

Edit 1: I'm using

cy.fixture('fixutre-file').then((data) => {
   const response = new TextDecoder().decode(res.body);

cy.intercept('https://example.com/', { method: 'POST' }, 
  (req) => {
    req.continue((res) => {
       if ("some condition for distinguishing the request I want to intercept, here") {
          res.send({ fixture: 'fixutre-file' });
       }
    });
  });
}):

to get the response and decide whether or not intercept this req and instead send back my fixture data. But the response constant is still some unreadable string. What's wrong with my approach?


Edit 2: Another approach that I used, was to use the cypress-protobuf package and encode my fixture.json file with the related protobuffer file:

cy.fixture('fixutre-file').then((data) => {
   cy.task('protobufEncode', {
        fixtureBody: data,
        message: 'the_message',
        protoFilePath: './protobuf/protofile.proto'
      }).then((encodedData) => {
cy.intercept('https://example.com/', { method: 'POST' }, 
  (req) => {
        /////// approach 1(didn't work): ///////
        // can't use this approach(because there is no identifier on 
        // req object to distinguish the requests I want to 
        // intercept)
        // if ("some condition based on `req` here") {
        //   req.reply(encodedData);
        // } else {
        //   req.continue();
        // }
         
        /////// approach 2: ///////
        // using encodedData to compare it with res.body
        req.continue(res => {
           // can't compare res.body with encodedData, because 
           // encodedData is an empty string!
        });
     }).as('needToWait');

     cy.wait('@needToWait').get('some selector').should('exist')
  });
}):

Now the problem is: encodedData is just an empty string, meaning it didn't work, so I can't compare the response with my fixture data to intercept the related request

Parsa
  • 79
  • 1
  • 10

1 Answers1

0

You can simply check for some value from the request that distinguishes it from the other requests. Request bodies and headers are often good places to start. Additionally, you can use req.alias to conditionally assign an alias if you need to wait for that specific call.

cy.intercept('/foo', (req) => {
  if (req.body.bar === true) { // or whatever logic indicates the call you want to intercept
    req.alias = 'baz'; // conditionally assign alias
    req.reply({foo: 'bar'}); // mock response
  } else {
    req.continue(); // do not mock response
  }
});

cy.get('something')
  .click()
  .wait('@baz'); // waits for your specific 'baz' call to happen.
agoff
  • 5,818
  • 1
  • 7
  • 20
  • Thanks. Still I can't convert the response which is an ArrayBuffer format, to actual js objects. My approach is to use `new TextDecoder().decode(res.body)`, but result is still not what I expected. I updated my question for this. – Parsa Jul 30 '22 at 07:17
  • Have you tried just using `.toJSON()`? `res.body.toJSON()`? – agoff Aug 01 '22 at 13:37
  • You mean JSON.parse(res.body)? Unfortunately no. Because the response body(res.body) is an ArrayBuffer – Parsa Aug 03 '22 at 08:39
  • Ah, had my syntax wrong -> something like this possibly? https://stackoverflow.com/a/71594294/11625850 – agoff Aug 03 '22 at 16:35
  • Doesn't work. Because `ArrayBuffer.isView(res.body)` check before executing `Buffer.from(res.body).toJSON()` , returns false(If I don't put that check, I get an error which says: `First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.` when using `Buffer.from(res.body)`). Maybe some kind of grpc client would solve the problem but I don't know how to leverage it – Parsa Aug 06 '22 at 11:59