Merge pull request #200 from jetzig-framework/improve-expectJob

Improve test App `requestJob`
This commit is contained in:
bobf 2025-05-05 13:39:38 +01:00 committed by GitHub
commit bb724b48f6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 68 additions and 12 deletions

View File

@ -25,8 +25,8 @@
.hash = "jetkv-0.0.0-zCv0fmCGAgCyYqwHjk0P5KrYVRew1MJAtbtAcIO-WPpT",
},
.zmpl = .{
.url = "https://github.com/jetzig-framework/zmpl/archive/c57fc9b83027e8c1459d9625c3509f59f0fb89f3.tar.gz",
.hash = "zmpl-0.0.1-SYFGBgdqAwDeA6xm4KAhpKoNrWs5CMQK6x447zhWclCs",
.url = "https://github.com/jetzig-framework/zmpl/archive/03cc97b52e80ac368f0dfe2e19c2b3dcdbf9f6ed.tar.gz",
.hash = "zmpl-0.0.1-SYFGBsSZAwBaIVdcokCVyM2azwVO3OTfaTTPddWERpyq",
},
.httpz = .{
.url = "https://github.com/karlseguin/http.zig/archive/37d7cb9819b804ade5f4b974b82f8dd0622225ed.tar.gz",

View File

@ -15,3 +15,11 @@ pub fn index(request: *jetzig.Request, data: *jetzig.Data) !jetzig.View {
return request.render(.ok);
}
test "index" {
var app = try jetzig.testing.app(std.testing.allocator, @import("routes"));
defer app.deinit();
const response = try app.request(.GET, "/background_jobs", .{});
try response.expectJob("example", .{ .foo = "bar" });
}

View File

@ -147,7 +147,7 @@ fn renderMarkdown(
if (zmpl.findPrefixed("views", prefixed_name)) |layout| {
view.data.content = .{ .data = content };
return try layout.render(view.data, jetzig.TemplateContext, .{}, .{});
return try layout.render(view.data, jetzig.TemplateContext, .{}, &.{}, .{});
} else {
std.debug.print("Unknown layout: {s}\n", .{layout_name});
return content;
@ -174,6 +174,7 @@ fn renderZmplTemplate(
view.data,
jetzig.TemplateContext,
.{},
&.{},
.{ .layout = layout },
);
} else {
@ -181,7 +182,7 @@ fn renderZmplTemplate(
return try allocator.dupe(u8, "");
}
} else {
return try template.render(view.data, jetzig.TemplateContext, .{}, .{});
return try template.render(view.data, jetzig.TemplateContext, .{}, &.{}, .{});
}
} else return null;
}

View File

@ -307,6 +307,7 @@ pub fn renderRedirect(self: *Request, state: RedirectState) !void {
self.response_data,
jetzig.TemplateContext,
.{ .request = self },
&.{},
.{},
);
} else try std.fmt.allocPrint(self.allocator, "Redirecting to {s}", .{state.location}),

View File

@ -435,6 +435,7 @@ fn renderTemplateWithLayout(
view.data,
jetzig.TemplateContext,
template_context,
&.{},
.{ .layout = layout },
);
} else {
@ -443,6 +444,7 @@ fn renderTemplateWithLayout(
view.data,
jetzig.TemplateContext,
template_context,
&.{},
.{},
);
}
@ -450,6 +452,7 @@ fn renderTemplateWithLayout(
view.data,
jetzig.TemplateContext,
template_context,
&.{},
.{},
);
}
@ -613,6 +616,7 @@ fn renderErrorView(
request.response_data,
jetzig.TemplateContext,
.{ .request = request },
&.{},
.{},
),
};

View File

@ -148,7 +148,7 @@ fn defaultHtml(
try data.addConst("jetzig_view", data.string(""));
try data.addConst("jetzig_action", data.string(""));
return if (jetzig.zmpl.findPrefixed("mailers", mailer.html_template)) |template|
try template.render(&data, jetzig.TemplateContext, .{}, .{})
try template.render(&data, jetzig.TemplateContext, .{}, &.{}, .{})
else
null;
}
@ -166,7 +166,7 @@ fn defaultText(
try data.addConst("jetzig_view", data.string(""));
try data.addConst("jetzig_action", data.string(""));
return if (jetzig.zmpl.findPrefixed("mailers", mailer.text_template)) |template|
try template.render(&data, jetzig.TemplateContext, .{}, .{})
try template.render(&data, jetzig.TemplateContext, .{}, &.{}, .{})
else
null;
}

View File

@ -66,7 +66,7 @@ pub const TestResponse = struct {
jobs: []Job,
pub const Header = struct { name: []const u8, value: []const u8 };
pub const Job = struct { name: []const u8, params: ?[]const u8 = null };
pub const Job = struct { name: []const u8, params: ?*jetzig.data.Value = null };
pub fn expectStatus(self: TestResponse, comptime expected: jetzig.http.status_codes.StatusCode) !void {
try testing.expectStatus(expected, self);
@ -299,13 +299,54 @@ pub fn expectJson(expected_path: []const u8, expected_value: anytype, response:
}
pub fn expectJob(job_name: []const u8, job_params: anytype, response: TestResponse) !void {
var actual_params_buf = std.ArrayList([]const u8).init(response.allocator);
defer actual_params_buf.deinit();
const value: ?*jetzig.data.Value = if (@TypeOf(job_params) == @TypeOf(null))
null
else
try jetzig.Data.zmplValue(job_params, response.allocator);
for (response.jobs) |job| {
comptime var has_args = false;
inline for (@typeInfo(@TypeOf(job_params)).Struct.fields) |field| {
has_args = true;
_ = field;
if (std.mem.eql(u8, job_name, job.name)) {
if (value != null and job.params != null) {
if (job.params.?.includes(value.?.*)) {
return;
} else {
try actual_params_buf.append(try job.params.?.toJson());
}
} else {
return;
}
}
if (!has_args and std.mem.eql(u8, job_name, job.name)) return;
}
if (actual_params_buf.items.len == 0) {
logFailure(
"Expected job " ++
jetzig.colors.cyan("{s}") ++
" to have been scheduled but job was not found in the queue.",
.{job_name},
);
} else {
const actual_params_formatted = try std.mem.join(
response.allocator,
"\n",
actual_params_buf.items,
);
defer response.allocator.free(actual_params_formatted);
logFailure(
"Expected params for job " ++
jetzig.colors.cyan("{s}") ++
":\n" ++
jetzig.colors.red("{s}\n") ++
"Actual job params:\n" ++
jetzig.colors.green("{s}"),
.{
job_name,
if (value) |v| try v.toJson() else "null",
actual_params_formatted,
},
);
}
return error.JetzigExpectJobError;
}

View File

@ -208,6 +208,7 @@ pub fn request(
while (try self.job_queue.popFirst(&data, "__jetzig_jobs")) |value| {
if (value.getT(.string, "__jetzig_job_name")) |job_name| try jobs.append(.{
.name = try allocator.dupe(u8, job_name),
.params = value,
});
}