Security News
The Risks of Misguided Research in Supply Chain Security
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
can-fixture
Advanced tools
can-fixture
intercepts an AJAX request and simulates
the response with a file or function. Use can-fixture
to:
can-fixture
is self contained and can be used without the rest of CanJS.
Play around with can-fixture in this JSBin!
fixture(ajaxSettings, requestHandler(...))
fixture(ajaxSettings, url)
fixture(ajaxSettings, data)
fixture(ajaxSettings, delay)
fixture(ajaxSettings, null)
fixture(methodAndUrl, url|data|requestHandler)
fixture(url, url|data|requestHandler)
fixture(fixtures)
fixture(restfulUrl, store)
fixture.store(baseItems, algebra)
fixture.store(count, makeItems, algebra)
Store
Store.prototype.getListData(request, response)
Store.prototype.getData(request, response)
Store.prototype.createData(request, response)
Store.prototype.updateData(request, response)
Store.prototype.destroyData(request, response)
Store.prototype.reset([baseItems])
Store.prototype.get(params)
Store.prototype.getList(set)
fixture.rand(min, max)
fixture.rand(choices, min, max)
fixture.delay
fixture.on
fixture.fixtures
If you are using Browserify
or StealJS, install it with NPM:
npm install can-fixture --save-dev
Then import
, require
, steal
, or define
the "can-fixture"
module:
var fixture = require("can-fixture");
Use the fixture
function to trap settings on a XMLHttpRequest object to a request handler.
The following traps all GET
type requests to /service
and results in a responseText
of "{\"message\":\"Hello World\"}"
:
fixture({url: "/service", method: "get"}, function(request, response){
response({message: "Hello World"});
})
The fixture
function has a wide variety of signatures that allow more control or easier shorthands. The previous
example could be written like:
fixture("GET /service", function(request, response){
return {message: "Hello World"};
})
Or:
fixture("GET /service", {message: "Hello World"});
You can forward a request to another url:
fixture("GET /service", "/fixtures/service.json");
Multiple fixture rules can be setup at once like:
fixture({
"GET /service": {message: "Hello World"},
"POST /service": function(request, response){
response(401,"{type: 'unauthorized'}");
}
});
Remove a fixture by calling fixture
with null in place of a responseHandler:
fixture("GET /service", null);
Finally, use fixture.store
to create a can-connect like-data store that simulates a restful service connected to a data store. Use can-set to describe the service's parameters.
// Describe the services parameters:
var todoAlgebra = new set.Algebra({
set.props.id("_id"),
set.props.boolean("completed"),
set.props.rangeInclusive("start","end"),
set.props.sort("orderBy"),
});
// Create a store:
var todoStore = fixture.store([
{
_id : 1,
name : 'Do the dishes',
complete: true
}, {
_id : 2,
name : 'Walk the dog',
complete: false
}],
todoAlgebra );
// Hookup urls to the store:
fixture("/todos/{_id}", todoStore);
If your urls aren't restful you can wire up the store manually:
fixture({
"GET /todos": todoStore.getListData,
"POST /todos": todoStore.createData,
"GET /todos/{_id}": todoStore.getData,
"PUT /todos/{_id}": todoStore.updateData,
"DELETE /todos/{_id}": todoStore.deleteData
});
The fixture
function has multiple signatures, most based on convenience. However,
we'll start with the lowest-level API which everything else is based:
fixture(ajaxSettings, requestHandler(...))
If an XHR request matches ajaxSettings
, calls requestHandler
with
the XHR requests data. Makes the XHR request responds with the return value of
requestHandler
or the result of calling its response
argument.
ajaxSettings
- An object that is used to match values on an XHR object, namely the
url
and method
. url
can be templated like /todos/{_id}
.requestHandler
- Handles the request and provides a response. The
next section details this function's use.The following traps requests to GET /todos
and responds with an array of data:
fixture({method: "get", url: "/todos"},
function(request, response, headers, ajaxSettings){
return {
data: [
{id: 1, name: "dishes"},
{id: 2, name: "mow"}
]
};
})
When adding a fixture, it will remove any identical fixtures from the list of fixtures. The last fixture added will be the first matched.
requestHandler(request, response(...), requestHeaders, ajaxSettings)
The request handler argument is called with:
request
- Information about the request. The request's data
property will
contain data from the request's querystring or request body.response
- A callback function that provides response information. The
next section details this function's use.requestHeaders
- Headers used to make the request.ajaxSettings
- The settings object used to match this request.Example:
fixture({method: "get", url: "/todos"},
function(request, response, headers, ajaxSettings){
request //-> {
// method: "get",
// url: "/todos",
// data: {complete: true}
// }
}
});
$.ajax({ method: "get", url: "/todos?complete=true" })
Templated url
data will be added to the requestHandler
's request
argument's data
property:
fixture({url: "/todos/{action}"},
function(request, response, headers, ajaxSettings){
request //-> {
// method: "post",
// url: "/todos",
// data: {action: delete}
// }
}
});
$.post("/todos/delete");
response(status, body, headers, statusText)
Used to detail a response.
status
- The HTTP response code. Ex: 200
.body
- A JS object that will be serialized and set as the responseText of the XHR object, or
the raw string text that will be set as the responseText of the XHR object.headers
- An object of HTTP response headers and values.statusText
- The status text of the response. Ex: "ok"
for 200.Example:
fixture({url: "/todos/{action}"},
function(request, response, headers, ajaxSettings){
response(
401,
{ message: "Unauthorized"},
{ "WWW-Authenticate": 'Basic realm="myRealm"'},
"unauthorized");
}
});
$.post("/todos/delete");
You don't have to provide every argument to response
. It can be called like:
// Just body
response({ message: "Hello World"});
// status and body
response(401, { message: "Unauthorized"});
// body and headers
response('{"message":"Unauthorized"}',{"WWW-Authenticate":'Basic realm="myRealm"'});
// status, body statusText
response(401, '{"message":"Unauthorized"}','unauthorized');
The default statusText
will be ok
for 200 <= status < 300, status === 304
and error
for everything else.
fixture(ajaxSettings, url)
Redirects the request to another url. This can be useful for simulating a response with a file.
fixture({url: "/tasks"}, "fixtures/tasks.json");
Placeholders available in the ajaxSettings
url will be available in the redirect url:
fixture({url: "/tasks/{id}"}, "fixtures/tasks/{id}.json");
fixture(ajaxSettings, data)
Responds with the JSON.stringify
result of data
.
fixture({url: "/tasks"}, {tasks: [{id: 1, complete: false}]});
fixture(ajaxSettings, delay)
Delays the ajax request from being made for delay
milliseconds.
fixture({url: "/tasks"}, 2000);
This doesn't simulate a response, but is useful for simulating slow connections.
fixture(ajaxSettings, null)
Removes the matching fixture from the list of fixtures.
fixture({url: "/tasks"}, "fixtures/tasks.json");
$.get("/tasks") // requests fixtures/tasks.json
fixture({url: "/tasks"}, null);
$.get("/tasks") // requests /tasks
fixture(methodAndUrl, url|data|requestHandler)
A short hand for creating an ajaxSetting
with a method
and url
.
fixture("GET /tasks", requestHandler );
// is the same as
fixture({method: "get", url: "/tasks"}, requestHandler );
The format is METHOD URL
.
fixture(url, url|data|requestHandler)
A short hand for creating an ajaxSetting
with just a url
.
fixture("/tasks", requestHandler);
// is the same as
fixture({url: "/tasks"}, requestHandler);
fixture(fixtures)
Create multiple fixtures at once.
{Object<methodAndUrl,url|data|requestHandler|store>}
- An mapping of methodAndUrl to
some response argument type.fixture({
"POST /tasks": function(){
return {id: Math.random()}
},
"GET /tasks": {data: [{id: 1, name: "mow lawn"}]},
"/people": "fixtures/people.json"
});
fixture(restfulUrl, store)
Wire up a restful API scheme to a store.
var todoAlgebra = new set.Algebra();
var todoStore = fixture.store([
{ id: 1, name: 'Do the dishes'},
{ id: 2, name: 'Walk the dog'}
], todoAlgebra);
fixture("/api/todos/{id}", todoStore);
This is a shorthand for wiring up the todoStore
as follows:
fixture({
"GET /api/todos": todoStore.getListData,
"GET /api/todos/{id}": todoStore.getData,
"POST /api/todos": todosStore.createData,
"PUT /api/todos/{id}": todos.updateData,
"DELETE /api/todos/{id}": todos.destroyData
});
fixture.store(baseItems, algebra)
Create a store that starts with baseItems
for a service layer
described by algebra
.
{Array}
- An array of items that will populate the store.{can.Algebra}
- A description of the service layer's parameters.// Describe the services parameters:
var todoAlgebra = new set.Algebra({
set.props.id("_id"),
set.props.boolean("completed"),
set.props.rangeInclusive("start","end"),
set.props.sort("orderBy"),
});
// Create a store with initial data.
// Pass [] if you want it to be empty.
var todoStore = fixture.store([
{
_id : 1,
name : 'Do the dishes',
complete: true
}, {
_id : 2,
name : 'Walk the dog',
complete: false
}],
todoAlgebra );
// Hookup urls to the store:
fixture("/todos/{_id}", todoStore);
fixture.store(count, makeItems, algebra)
Similar to fixture.store(baseItems, algebra)
, except that
it uses makeItems
to create count
entries in the store.
// Describe the services parameters:
var todoAlgebra = new set.Algebra({ ... });
// Create a store with initial data.
// Pass [] if you want it to be empty.
var todoStore = fixture.store(
1000,
function(i){
return {
_id : i+1,
name : 'Todo '+i,
complete: fixture.rand([true, false],1)[0]
}
},
todoAlgebra );
// Hookup urls to the store:
fixture("/todos/{_id}", todoStore);
Store
The following documents the methods on a store object returned by
fixture.store
.
Store.prototype.getListData(request, response)
A requestHandler
that gets multiple items from the store.
fixture("GET /api/todos", todoStore.getListData);
Store.prototype.getData(request, response)
A requestHandler
that gets a single item from the store.
fixture("GET /api/todos/{_id}", todoStore.getData);
Store.prototype.createData(request, response)
A requestHandler
that creates an item in the store.
fixture("POST /api/todos", todoStore.createData);
Store.prototype.updateData(request, response)
A requestHandler
that updates an item in the store.
fixture("PUT /api/todos/{_id}", todoStore.updateData);
Store.prototype.destroyData(request, response)
A requestHandler
that removes an item from the store.
fixture("DELETE /api/todos/{_id}", todoStore.destroyData)
Store.prototype.reset([baseItems])
Sets the items in the store to their original state or to baseItems
if it's passed.
// Creates a store with one item.
var todoStore = fixture.store(
[{id: 1, name: "dishes"}],
new set.Algebra());
fixture("/todos/{id}", todoStore)
todoStore.getList({}).length //-> 1
// delete that item
$.ajax({url: "todos/1", method: "delete"}).then(function(){
return todoStore.getList({}).length //-> 0
}).then(function(){
// calling reset adds it back
todoStore.reset();
todoStore.getList({}).length //-> 1
});
Store.prototype.get(params)
Returns a single item's data from the store.
todoStore.get({id: 1}) //-> {id: 1, name: "dishes"}
Store.prototype.getList(set)
Returns the matching items from the store like: {data: [...]}
.
todoStore.get({name: "dishes"}) //-> {data: [{id: 1, name: "dishes"}]}
fixture.rand(min, max)
Returns a random integer in the range [min, max]. If only one argument is provided, returns a random integer from [0, max].
fixture.rand(1, 10) //-> Random number between 1 and 10 inclusive.
fixture.rand(10) //-> Random number between 0 and 10 inclusive.
fixture.rand(choices, min, max)
An array of between min and max random items from choices. If only min
is
provided, max
will equal min
. If both max
ad min
are not provided,
min
will be 1 and max
will be choices.length
.
// pick a random number of items from an array
fixture.rand(["a","b","c"]) //-> ["c"]
fixture.rand(["a","b","c"]) //-> ["b","a"]
// pick one item from an array
fixture.rand(["a","b","c"],1) //-> ["c"]
// get one item from an array
fixture.rand(["a","b","c"],1)[0] //-> "b"
// get 2 or 3 items from the array
fixture.rand(["a","b","c"],2,3) //-> ["c","a","b"]
fixture.delay
Sets the delay until a response is fired in milliseconds.
fixture.delay = 1000; // 1 second delay
fixture.on
Turns the fixtures on or off. Defaults to true
for on.
fixture.on = false; //-> AJAX requests will not be trapped
To remove a fixture you can also use fixture(ajaxSetting, null)
.
fixture.fixtures
The list of currently active fixtures.
FAQs
Intercept AJAX requests and simulate responses.
We found that can-fixture demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 15 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Snyk's use of malicious npm packages for research raises ethical concerns, highlighting risks in public deployment, data exfiltration, and unauthorized testing.
Research
Security News
Socket researchers found several malicious npm packages typosquatting Chalk and Chokidar, targeting Node.js developers with kill switches and data theft.
Security News
pnpm 10 blocks lifecycle scripts by default to improve security, addressing supply chain attack risks but sparking debate over compatibility and workflow changes.