0

Ok these tests were passing a few bit ago. I have made no changes to which version of jasmine I'm using but... can anyone see obvious syntax errors here?

describe("ajax return", function() {
  beforeEach(function() {
    ajaxSpy = spyOn($, "ajax")
  })
  describe("on success", function() {
    beforeEach(async function() {
      ajaxSpy.and.callFake(function(e) {
        e.success({"success":true, "remove":{1:"test"},"assign_prestock":"test2"})
      })
      await catalogDOM.syncAvailability(null)
    })
    it("should call", function() {
      ...
    })
  })
})

When running, I'm getting this error:

1_catalogDOM_spec.js:518 Uncaught (in promise) TypeError: e.success is not a function

UPDATE code for catalogDOM.syncAvailability

catalogDOM.syncAvailability: function(item_name_id) {
  return new Promise(function(resolve, reject) {
    $.ajax({
      type:"POST",
      url: "/retrieve-options-availability",
      dataType:"json",
      contentType:"application/json",
      data: JSON.stringify(params)
    })
    .done(function(response, status_string, jqxhr) {
       if (response["success"] == true) {
         resolve()
       } else {
         reject(response["message"])
       }
    })
    .fail(function(jqxhr, error_string, exception_object){
      reject("Error loading availability. Refresh & try again or contact us if this persists.")
    })
  }
james
  • 3,989
  • 8
  • 47
  • 102

1 Answers1

0

Try doing this to debug:

ajaxSpy.and.callFake(function(e) {
        // add console.log here !!
        console.log('e: ', e);
        e.success({"success":true, "remove":{1:"test"},"assign_prestock":"test2"})
      })

Apparently, .success is not a function anymore and you can look at the value of e there. I am thinking e is the argument for what's provided in $.ajax(/* e is here */);.

Looking at the documentation here: https://api.jquery.com/jquery.ajax/, I think we need to mock a done function.

Try this:

ajaxSpy.and.callFake(function (e) {
  return {
    done: function () {
       return {
        "success":true, 
        "remove":{1:"test"},
        "assign_prestock":"test2",
        // edit - create a fail function that's empty here
        fail: function() {
          // leave empty
        }
      };
    }
  };
});

Edit Instead of doing a spy on ajaxSpy, try spying on catalogDOM directly. Something like this:

spyOn(catalogDOM, 'syncAvailability').and.resolveTo({/* Mock value here */ });

Or

spyOn(catalogDOM, 'syncAvailability').and.returnValue(Promise.resolve({ /* Mock value here */ });

And then you don't have to await it.

AliF50
  • 16,947
  • 1
  • 21
  • 37
  • Yes, but why... What I get NOW is: `e = {contentType: "application/json", data: "\"params\"", dataType: "json", type: "POST", url: "/retrieve-options-availability"}`. Looking at the last time the spec passed, `e` had 2 additional functions: `{error: ƒ (jqxhr, error_string, exception_object), success: ƒ (response, status_string, jqxhr)}` – james Sep 08 '22 at 01:18
  • Did the version of jQuery (I assume) change? – AliF50 Sep 08 '22 at 12:40
  • 1
    oh you know what... it totally did.. `2.2.4` to `3.6.0` – james Sep 08 '22 at 17:21
  • Yes, I think that can be an issue especially the major version going from `2` to `3`. – AliF50 Sep 08 '22 at 17:41
  • i don't suppose you have ideas on how to fix? the documentation is really really sparse... the writers of jasmine did write a separate plugin for `jasmine-ajax` but if i didn't want to use that and just want to keep my existing strategy of using `.callFake`, i haven't found many resources there – james Sep 08 '22 at 17:56
  • Check out my edit. – AliF50 Sep 08 '22 at 18:57
  • ugh this is so frustrating... that success error has disappeared. but the `ajaxSpy.and.callFake` is causing an error that `$(ajax).done().fail()` is not a function, and I've triple checked that jasmine is loading `jquery 3.6.0` which does use such syntax. If I remove the `callFake` line, that error goes away, but then of course since there's no spy, I get `Cannot read properties of undefined (reading 'done')` – james Sep 08 '22 at 23:37
  • Ok, check out my edit. Try creating an empty `fail` function on the `done` object. – AliF50 Sep 09 '22 at 12:41
  • that gets an error that i don't even know why... `Error: Timeout - Async callback was not invoked within 5000ms (set by jasmine.DEFAULT_TIMEOUT_INTERVAL)` – james Sep 09 '22 at 21:10
  • I am thinking it's because this line's `await catalogDOM.syncAvailability(null)` promise never resolves. – AliF50 Sep 12 '22 at 12:44
  • I added that code so you can see it. It's not resolving, because that function returns a promise that resolves upon ajax submission, but the `callFake` isn't working. Like neither the `.done` or `.fail` execute in either the original code or the edited – james Sep 16 '22 at 00:51
  • Ok, mocking `ajax` is probably difficult. Try spying on the the `catalogDOM` itself. Check out my edit. – AliF50 Sep 16 '22 at 12:56
  • well but that's the thing... I'm trying to spy on the `ajax` because I want to test the right functions are executed depending on if it succeeds or fails... The `callFake` used to work before the version change, that's the problem... – james Sep 16 '22 at 17:04
  • Sorry, I am not sure. See if the following answers help you: https://stackoverflow.com/a/42007610/7365461. – AliF50 Sep 16 '22 at 17:09