{"size": 6869, "ext": "js", "max_stars_repo_path": "spec/store/fields/has-many-spec.js", "max_stars_repo_name": "kellyjensen/json-api-store", "max_stars_repo_stars_event_min_datetime": "2015-08-25T21:12:10.000Z", "max_stars_repo_stars_event_max_datetime": "2021-06-03T18:55:38.000Z", "max_issues_repo_path": "spec/store/fields/has-many-spec.js", "max_issues_repo_name": "kellyjensen/json-api-store", "max_issues_repo_issues_event_min_datetime": "2015-08-21T05:50:01.000Z", "max_issues_repo_issues_event_max_datetime": "2017-06-05T09:36:35.000Z", "max_forks_repo_path": "spec/store/fields/has-many-spec.js", "max_forks_repo_name": "kellyjensen/json-api-store", "max_forks_repo_forks_event_min_datetime": "2015-11-19T19:22:02.000Z", "max_forks_repo_forks_event_max_datetime": "2018-06-28T19:39:55.000Z"}
{"max_stars_count": 84, "max_issues_count": 50, "max_forks_count": 12, "avg_line_length": 26.2175572519, "max_line_length": 152, "alphanum_fraction": 0.562381715}
import test from "tape-catch";
import Store from "../../../src/store";

test("hasMany must return the correct type attribute", function (t) {
  t.plan(4);
  t.equal(Store.hasMany().type, "has-many");
  t.equal(Store.hasMany("example").type, "has-many");
  t.equal(Store.hasMany({}).type, "has-many");
  t.equal(Store.hasMany("example", {}).type, "has-many");
});

test("hasMany must return default value as an empty array", function (t) {
  t.plan(1);
  t.deepEqual(Store.hasMany().default, []);
});

test("hasMany must return a serialize function that maps a relationship to data", function (t) {
  var store = new Store();
  var field = Store.hasMany();
  var resource = {
    type: "products",
    id: "1",
    categories: [
      {
        type: "categories",
        id: "2"
      },
      {
        type: "categories",
        id: "4"
      }
    ]
  };
  var data = {
    "relationships": {}
  };
  t.plan(1);
  store.define("categories", {});
  store.define("products", {});
  field.serialize.call(store, resource, data, "categories");
  t.deepEqual(data, {
    relationships: {
      categories: {
        data: [
          {
            type: "categories",
            id: "2"
          },
          {
            type: "categories",
            id: "4"
          }
        ]
      }
    }
  });
});

test("hasMany must return a serialize function that skips missing relationships", function (t) {
  var store = new Store();
  var field = Store.hasMany();
  var resource = {
    type: "products",
    id: "1"
  };
  var data = {
    "relationships": {}
  };
  t.plan(1);
  store.define("categories", {});
  store.define("products", {});
  field.serialize.call(store, resource, data, "categories");
  t.deepEqual(data, {
    relationships: {}
  });
});

// TODO: serialize function uses the name option if it's provided

test("hasMany must return a serialize function that uses the name option if it's provided", function (t) {
  var store = new Store();
  var field = Store.hasMany("categories-x");
  var resource = {
    type: "products",
    id: "1",
    categories: [
      {
        type: "categories",
        id: "2"
      },
      {
        type: "categories",
        id: "4"
      }
    ]
  };
  var data = {
    "relationships": {}
  };
  t.plan(1);
  store.define("categories", {});
  store.define("products", {});
  field.serialize.call(store, resource, data, "categories");
  t.deepEqual(data, {
    relationships: {
      "categories-x": {
        data: [
          {
            type: "categories",
            id: "2"
          },
          {
            type: "categories",
            id: "4"
          }
        ]
      }
    }
  });
});

test("hasMany must return a deserialize function that maps to the relation described in the data property", function (t) {
  var store = new Store();
  var field = Store.hasMany("categories");
  var data = {
    "type": "products",
    "id": "1",
    "relationships": {
      "categories": {
        "data": [
          {
            "type": "categories",
            "id": "2"
          },
          {
            "type": "categories",
            "id": "4"
          }
        ]
      }
    }
  };
  t.plan(2);
  store.define("categories", {});
  store.define("products", {});
  t.equal(field.deserialize.call(store, data).length, 2);
  t.deepEqual(field.deserialize.call(store, data).map(c => c.id).sort(), [ "2", "4" ]);
});

test("hasMany must return a deserialize function that uses the key param when the name isn't provided", function (t) {
  var store = new Store();
  var field = Store.hasMany();
  var data = {
    "type": "products",
    "id": "1",
    "relationships": {
      "categories": {
        "data": [
          {
            "type": "categories",
            "id": "2"
          },
          {
            "type": "categories",
            "id": "4"
          }
        ]
      }
    }
  };
  t.plan(2);
  store.define("categories", {});
  store.define("products", {});
  t.equal(field.deserialize.call(store, data, "categories").length, 2);
  t.deepEqual(field.deserialize.call(store, data, "categories").map(c => c.id).sort(), [ "2", "4" ]);
});

test("hasMany must return a deserialize function that returns an empty array when the relationship data field is null or an empty array", function (t) {
  var store = new Store();
  var data = {
    "type": "products",
    "id": "1",
    "relationships": {
      "categories": {
        "data": []
      },
      "comments": {
        "data": null
      }
    }
  };
  t.plan(4);
  t.deepEqual(Store.hasMany("categories").deserialize.call(store, data), []);
  t.deepEqual(Store.hasMany().deserialize.call(store, data, "categories"), []);
  t.deepEqual(Store.hasMany("comments").deserialize.call(store, data), []);
  t.deepEqual(Store.hasMany().deserialize.call(store, data, "comments"), []);
});

test("hasMany must return a deserialize function that returns undefined when the relationship data field is missing", function (t) {
  var store = new Store();
  var data = {
    "type": "products",
    "id": "1",
    "relationships": {
      "categories": {}
    }
  };
  t.plan(2);
  t.equal(Store.hasMany("categories").deserialize.call(store, data), undefined);
  t.equal(Store.hasMany().deserialize.call(store, data, "categories"), undefined);
});

test("hasMany must return a deserialize function that returns undefined when the relationship type field is missing", function (t) {
  var store = new Store();
  var data = {
    "type": "products",
    "id": "1",
    "relationships": {}
  };
  t.plan(2);
  t.equal(Store.hasMany("categories").deserialize.call(store, data), undefined);
  t.equal(Store.hasMany().deserialize.call(store, data, "categories"), undefined);
});

test("hasMany must return a deserialize function that returns undefined when the relationship field is missing", function (t) {
  var store = new Store();
  var data = {
    "type": "products",
    "id": "1"
  };
  t.plan(2);
  t.equal(Store.hasMany("categories").deserialize.call(store, data), undefined);
  t.equal(Store.hasMany().deserialize.call(store, data, "categories"), undefined);
});

test("hasMany must return a deserialize function that passes on an inverse option", function (t) {
  t.plan(2);
  t.equal(Store.hasMany({ inverse: "foo" }).inverse, "foo");
  t.equal(Store.hasMany("example", { inverse: "foo" }).inverse, "foo");
});

test("hasMany must throw an error a relationship's type hasn't been defined", function (t) {
  var store = new Store();
  var field = Store.hasMany();
  var data = {
    "type": "products",
    "id": "44",
    "relationships": {
      "categories": {
        "data": [
          { "type": "categories", "id": "34" }
        ]
      }
    }
  };
  t.plan(1);
  store.define("products", {});
  t.throws(function () {
    field.deserialize.call(store, data, "categories");
  }, /Unknown type 'categories'/);
});
