Can-connect models and HATEOAS

Hi all,

We’re building a client application that interacts with a HTTP API which provides a way of navigating through the resource relations using hypermedia links. Typically we need to instruct our models to use a full custom URL for the getData and getListData interfaces. I’m able to overwrite these methods as shown below and it works at expected.

My challenge now is how to setup the fixtures to test these models. I’m only able to get the tests pass if I don’t put any query parameters in the fixture key. I’m able to observe that even though the fixture is added the exact or loose matches don’t return the fixture.

Note: I’m aware that the URI /todos?id=string/with/slashes to fetch a single resource might not conform but these resources unique identifiers include slashes making it difficult to model it with as a path parameter.

var DefineMap = require("can-define/map/map");
var DefineList = require("can-define/list/list");
var connect = require("can-connect");
var set = require("can-set");
var QUnit = require("steal-qunit");
var fixture = require("can-fixture");

const Todo = DefineMap.extend({
  id: "string"
});

Todo.List = DefineList.extend({
  "#": Todo
});

Todo.algebra = new set.Algebra(set.props.id("id"));

Todo.connection = connect([
  require("can-connect/constructor/"),
  require("can-connect/can/map/"),
  require("can-connect/constructor/store/"),
  require("can-connect/data/callbacks/"),
  require("can-connect/data/parse/"),
  require("can-connect/data/url/")
], {
  Map: Todo,
  List: Todo.List,
  url: {
    getData: "{url}"
    getListData: "{url}"
  }
});

QUnit.module("Todo module");

QUnit.test("full custom url", function(assert) {

  var string-with-slashes = "string/with/slashes";

  fixture("GET /todos?id=A", {id: string-with-slashes});

  QUnit.stop();
  Todo.get({url: "/todos?id=string/with/slashes"}).then(todo => {
    assert.equal(todo.id, string-with-slashes);
    QUnit.start();
  });

});

Can you match just /todos with your fixture?

It seems that to make the fixture return I just need to remove the query parameters. The resource URI part of the URL will match which appears to be enough to get the loose match in can-fixture/core.js#get(). But this way its more difficult to define a collection of fixtures for various test scenarios related to the same resource.

Can you create an issue in can-fixture with what you’d like to see. Thanks!

Just created an issue for it.

This is not an issue with the behavior data/url. getData/getListData implementations support full custom URI.
As pointed out by Chris in can-fixture #115 this is a known limitation referred in can-fixture docs at https://canjs.com/doc/can-fixture/types/ajaxSettings.html and there are at least two possible workarounds.

fixture("GET /todos", (req, res) => {
    console.log(req, res)
    if (req.data.url.indexOf("id=A") !=== -1) {
      res({id: 'A'});
    } else if () {
      res({id: 'B'});
    }
    res(null)
  });

OR using a static resouce url

fixture({method: "GET", url: "/todos", data: {id: "A"}}, {id: "A", name: "A"});
fixture({method: "GET", url: "/todos", data: {id: "B"}}, {id: "B", name: "B"});

Thanks for the help.