Closed thesmart closed 3 years ago
Hi @thesmart ๐
superoak ultimately wraps superdeno and superagent to expose the API for Oak servers.
Setting headers can be performed via the .set()
method https://visionmedia.github.io/superagent/#setting-header-fields and accessible via the response object in the .end()
or .then()
methods https://github.com/asos-craigmorten/superdeno#endfn, https://visionmedia.github.io/superagent/#response-properties.
superoak does not save cookies by default in keeping with superagent for Node https://visionmedia.github.io/superagent/#agents-for-global-state. If having a persistent cookie jar is what youโre requesting please let me know and can look into that.
I think what you want can be achieved by reading the header response from your first request, extracting the value and then passing as a header to your second request ๐ though being honest Iโm not 100% clear if that is what you want to achieve ( need coffee! ) ๐ if so then could start with that, and exposing an agent which can automatically handle cookies for you in future can be the next goal for this project.
If Iโm completely off the mark, please can you provide a small code snippet ( code block or gist etc ) for the server ( or sim ) youโre trying to test?
Thanks, @cmorten! I didn't realize how SuperOak, SuperDeno and SuperAgent overlapped, but now it seems obvious from your great answer and I wonder now why I couldn't figure this out last night. Probably too tired. ๐ Your answer makes it clear how I can move forward. ๐
I think I confused myself when I realized the superoak(app)
instances can't be reused due to the network is offline
issue mentioned in docs. This morning, I was curious if I could patch that network is offline
issue, but realized it's probably due to Oak's architecture. Oak relies on serve
to produce requests, and those requests are processed only after .listen()
is awaited on. So SuperOak has to close
via abort signal in order for the assertion chain to be evaluated. This is SuperAwkward (ha!). It would be great if Oak didn't require a network connection for testing.
Example:
class MockServer {
serverClosed = false;
requestStack: ServerRequest[];
constructor(requestStack: ServerRequest[]) {
this.requestStack = requestStack;
}
close(): void {
this.serverClosed = true;
}
async *[Symbol.asyncIterator]() {
for await (const request of this.requestStack) {
yield request;
}
}
}
/**
* Make a mock Oak application that can process requests
* and middleware for testing purposes.
*
* ```js
* const app = new MockApplication();
* app.use(middleware);
* app.makeRequest("/"
* ```
*/
export class MockApplication extends Application {
requestStack: ServerRequest[] = [];
responseStack: ServerResponse[] = [];
constructor() {
super({
serve: (addr: string | ListenOptions): Server => {
return new MockServer(this.requestStack) as Server;
}
});
}
makeRequest(
url = "/",
headersInit: string[][] = [["host", "example.com"]]
) {
this.requestStack.push({
url,
headers: new Headers(headersInit),
respond: (response: ServerResponse) => {
this.responseStack.push(response);
return Promise.resolve();
},
proto: "HTTP/1.1"
} as any);
}
async listen() {
// this port doesn't actually get used
await super.listen(":1337")
// clear the request stack after handling them
while (this.requestStack.pop()) {};
}
}
Deno.test("MockApplication can be used to test middleware.", async function() {
const app = new MockApplication();
let middlewareCalled = 0;
app.use((ctx: Context, next: () => Promise<void>) => {
middlewareCalled += 1;
})
app.makeRequest();
app.makeRequest();
await app.listen();
assertEquals(middlewareCalled, 2);
app.makeRequest();
await app.listen();
assertEquals(middlewareCalled, 3);
})
This is still pretty awkward, but maybe could be made better by composing the assertions like how SuperAgent does it.
Closing this issue because it's not an "issue" and more of a conversation.
How to test cookie based sessions?
Setup:
Details
Hello, I'm trying to figure out how to use superoak to test multiple routes that would sign-up and sign-in a user via session cookie. Is there any way to read headers from response and pass them to a request?