Rudimentary test cases for ParseBody

This commit is contained in:
jaina heartles 2022-11-27 02:21:22 -08:00
parent 8aa4f900f6
commit b99a0095d4

View file

@ -591,12 +591,13 @@ const BaseContentType = enum {
other,
};
fn parseBodyFromRequest(comptime T: type, content_type: BaseContentType, reader: anytype, alloc: std.mem.Allocator) !T {
//@compileLog(T);
fn parseBodyFromRequest(comptime T: type, content_type: ?[]const u8, reader: anytype, alloc: std.mem.Allocator) !T {
// Use json by default for now for testing purposes
const parser_type = matchContentType(content_type) orelse .json;
const buf = try reader.readAllAlloc(alloc, 1 << 16);
defer alloc.free(buf);
switch (content_type) {
switch (parser_type) {
.octet_stream, .json => {
const body = try json_utils.parse(T, buf, alloc);
defer json_utils.parseFree(body, alloc);
@ -640,10 +641,8 @@ pub fn ParseBody(comptime Body: type) type {
return next.handle(req, res, new_ctx, {});
}
const base_content_type = matchContentType(content_type);
var stream = req.body orelse return error.NoBody;
const body = try parseBodyFromRequest(Body, base_content_type orelse .json, stream.reader(), ctx.allocator);
const body = try parseBodyFromRequest(Body, content_type, stream.reader(), ctx.allocator);
defer util.deepFree(ctx.allocator, body);
return next.handle(
@ -659,6 +658,47 @@ pub fn parseBody(comptime Body: type) ParseBody(Body) {
return .{};
}
test "parseBodyFromRequest" {
const testCase = struct {
fn case(content_type: []const u8, body: []const u8, expected: anytype) !void {
var stream = std.io.StreamSource{ .const_buffer = std.io.fixedBufferStream(body) };
const result = try parseBodyFromRequest(@TypeOf(expected), content_type, stream.reader(), std.testing.allocator);
defer util.deepFree(std.testing.allocator, result);
try util.testing.expectDeepEqual(expected, result);
}
}.case;
const Struct = struct {
id: usize,
};
try testCase("application/json", "{\"id\": 3}", Struct{ .id = 3 });
try testCase("application/x-www-form-urlencoded", "id=3", Struct{ .id = 3 });
}
test "parseBody" {
const Struct = struct {
foo: []const u8,
};
const body =
\\{"foo": "bar"}
;
var stream = std.io.StreamSource{ .const_buffer = std.io.fixedBufferStream(body) };
var headers = http.Fields.init(std.testing.allocator);
defer headers.deinit();
try parseBody(Struct).handle(
.{ .body = @as(?std.io.StreamSource, stream), .headers = headers },
.{},
.{ .allocator = std.testing.allocator },
struct {
fn handle(_: anytype, _: anytype, _: anytype, ctx: anytype, _: void) !void {
try util.testing.expectDeepEqual(Struct{ .foo = "bar" }, ctx.body);
}
}{},
);
}
/// Parses query parameters as defined in query.zig
pub fn ParseQueryParams(comptime QueryParams: type) type {
return struct {