add handler/server tests
This commit is contained in:
parent
0726cc0299
commit
d20b49dc90
2 changed files with 265 additions and 2 deletions
|
|
@ -76,7 +76,7 @@ fn handleWeather(ctx: *Context, req: *httpz.Request, res: *httpz.Response) !void
|
||||||
try handler.handleWeather(&ctx.options, req, res, client_ip);
|
try handler.handleWeather(&ctx.options, req, res, client_ip);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getClientIp(req: *httpz.Request, buf: []u8) ![]const u8 {
|
pub fn getClientIp(req: *httpz.Request, buf: []u8) ![]const u8 {
|
||||||
// Check X-Forwarded-For header first (for proxies)
|
// Check X-Forwarded-For header first (for proxies)
|
||||||
if (req.header("x-forwarded-for")) |xff| {
|
if (req.header("x-forwarded-for")) |xff| {
|
||||||
return parseXForwardedFor(xff);
|
return parseXForwardedFor(xff);
|
||||||
|
|
@ -114,7 +114,7 @@ pub fn deinit(self: *Server) void {
|
||||||
self.httpz_server.deinit();
|
self.httpz_server.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
const MockHarness = struct {
|
pub const MockHarness = struct {
|
||||||
allocator: std.mem.Allocator,
|
allocator: std.mem.Allocator,
|
||||||
config: Config,
|
config: Config,
|
||||||
geoip: *GeoIp,
|
geoip: *GeoIp,
|
||||||
|
|
@ -241,6 +241,16 @@ test "handleWeather: default endpoint uses IP address" {
|
||||||
try handler.handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
try handler.handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
try ht.expectStatus(200);
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody(
|
||||||
|
\\<pre>Weather report: 73.158.64.1
|
||||||
|
\\
|
||||||
|
\\<span style="color:#ffff00"> \ / </span> Clear
|
||||||
|
\\<span style="color:#ffff00"> .-. </span> <span style="color:#d7ff00">+68(+68)</span> °F
|
||||||
|
\\<span style="color:#ffff00"> ― ( ) ― </span> ↓ <span style="color:#6c6c6c">3</span> mph
|
||||||
|
\\<span style="color:#ffff00"> `-' </span> 6 mi
|
||||||
|
\\<span style="color:#ffff00"> / \ </span> 0.0 in
|
||||||
|
\\</pre>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
test "handleWeather: x-forwarded-for with multiple IPs" {
|
test "handleWeather: x-forwarded-for with multiple IPs" {
|
||||||
|
|
|
||||||
|
|
@ -198,3 +198,256 @@ fn determineFormat(params: QueryParams, user_agent: ?[]const u8) Formatted.Forma
|
||||||
return .ansi;
|
return .ansi;
|
||||||
return .html;
|
return .html;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "handler: help page" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/:help");
|
||||||
|
ht.param("location", ":help");
|
||||||
|
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, "127.0.0.1");
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: translation page" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/:translation");
|
||||||
|
ht.param("location", ":translation");
|
||||||
|
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, "127.0.0.1");
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: favicon" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/favicon.ico");
|
||||||
|
ht.param("location", "favicon.ico");
|
||||||
|
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, "127.0.0.1");
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format j1 (json)" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=j1");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectHeader("Content-Type", "application/json; charset=UTF-8");
|
||||||
|
try ht.expectBody(
|
||||||
|
\\{"current_condition":{"temp_C":20,"weatherCode":"clear","weatherDesc":[{"value":"Clear"}],"humidity":50,"windspeedKmph":5,"winddirDegree":0,"pressure":1013,"precipMM":0},"weather":[]}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format p1 (prometheus)" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=p1");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody(
|
||||||
|
\\# HELP temperature_feels_like_celsius Feels Like Temperature in Celsius
|
||||||
|
\\temperature_feels_like_celsius{forecast="current"} 20
|
||||||
|
\\# HELP temperature_feels_like_fahrenheit Feels Like Temperature in Fahrenheit
|
||||||
|
\\temperature_feels_like_fahrenheit{forecast="current"} 68
|
||||||
|
\\# HELP cloudcover_percentage Cloud Coverage in Percent
|
||||||
|
\\cloudcover_percentage{forecast="current"} 0
|
||||||
|
\\# HELP humidity_percentage Humidity in Percent
|
||||||
|
\\humidity_percentage{forecast="current"} 50
|
||||||
|
\\# HELP precipitation_mm Precipitation (Rainfall) in mm
|
||||||
|
\\precipitation_mm{forecast="current"} 0.0
|
||||||
|
\\# HELP pressure_hpa Air pressure in hPa
|
||||||
|
\\pressure_hpa{forecast="current"} 1013
|
||||||
|
\\# HELP temperature_celsius Temperature in Celsius
|
||||||
|
\\temperature_celsius{forecast="current"} 20
|
||||||
|
\\# HELP temperature_fahrenheit Temperature in Fahrenheit
|
||||||
|
\\temperature_fahrenheit{forecast="current"} 68
|
||||||
|
\\# HELP uv_index Ultraviolet Radiation Index
|
||||||
|
\\uv_index{forecast="current"} 0
|
||||||
|
\\# HELP visibility Visible Distance in Kilometres
|
||||||
|
\\visibility{forecast="current"} 10
|
||||||
|
\\# HELP weather_code Code to describe Weather Condition
|
||||||
|
\\weather_code{forecast="current"} 800
|
||||||
|
\\# HELP winddir_degree Wind Direction in Degree
|
||||||
|
\\winddir_degree{forecast="current"} 0
|
||||||
|
\\# HELP windspeed_kmph Wind Speed in Kilometres per Hour
|
||||||
|
\\windspeed_kmph{forecast="current"} 5
|
||||||
|
\\# HELP windspeed_mph Wind Speed in Miles per Hour
|
||||||
|
\\windspeed_mph{forecast="current"} 3.106856
|
||||||
|
\\# HELP observation_time Minutes since start of the day the observation happened
|
||||||
|
\\observation_time{forecast="current"} 0
|
||||||
|
\\# HELP weather_desc Weather Description
|
||||||
|
\\weather_desc{forecast="current", description="Clear"} 1
|
||||||
|
\\# HELP winddir_16_point Wind Direction on a 16-wind compass rose
|
||||||
|
\\winddir_16_point{forecast="current", description="N"} 1
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format v2" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=v2");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
// Should we have 2 empty lines?
|
||||||
|
try ht.expectBody(
|
||||||
|
\\Weather report: 73.158.64.1
|
||||||
|
\\
|
||||||
|
\\ Current conditions
|
||||||
|
\\ Clear
|
||||||
|
\\ 🌡️ 20.0°C (68.0°F)
|
||||||
|
\\ 💧 50%
|
||||||
|
\\ 🌬️ 5.0 km/h N
|
||||||
|
\\ 🔽 1013.0 hPa
|
||||||
|
\\ 💦 0.0 mm
|
||||||
|
\\
|
||||||
|
\\
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format custom (%c)" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=%c");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody("☀️");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format line 1" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=1");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody("Test: ☀️ 20°C");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format line 2" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=2");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody("Test: ☀️ 20°C 🌬️N5km/h");
|
||||||
|
}
|
||||||
|
|
||||||
|
test "handler: format line 3" {
|
||||||
|
const allocator = std.testing.allocator;
|
||||||
|
const MockHarness = @import("Server.zig").MockHarness;
|
||||||
|
|
||||||
|
var harness = try MockHarness.init(allocator);
|
||||||
|
defer harness.deinit();
|
||||||
|
|
||||||
|
var ht = httpz.testing.init(.{});
|
||||||
|
defer ht.deinit();
|
||||||
|
|
||||||
|
ht.url("/73.158.64.1?format=3");
|
||||||
|
ht.param("location", "73.158.64.1");
|
||||||
|
|
||||||
|
var client_ip_buf: [47]u8 = undefined;
|
||||||
|
const client_ip = try @import("Server.zig").getClientIp(ht.req, &client_ip_buf);
|
||||||
|
try handleWeather(&harness.opts, ht.req, ht.res, client_ip);
|
||||||
|
|
||||||
|
try ht.expectStatus(200);
|
||||||
|
try ht.expectBody("Test: ☀️ 20°C 🌬️N5km/h 💧50%%");
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue