1- require 'test_helper'
1+ # typed: true
2+
3+ require "test_helper"
24
35class LogstructTest < ActionDispatch ::IntegrationTest
46 setup do
@@ -14,141 +16,155 @@ class LogstructTest < ActionDispatch::IntegrationTest
1416 # Restore original logger
1517 @log_device . instance_variable_set ( :@dev , @original_log_device )
1618 end
17-
19+
1820 test "basic logging produces structured JSON logs" do
1921 get "/logging/basic"
22+
2023 assert_response :success
21-
24+
2225 # Parse the logs to verify structured format
2326 log_entries = parse_log_entries
24-
27+
2528 # Check that we have at least 3 log entries (info, warn, debug)
26- assert log_entries . length >= 3 , "Should have at least 3 log entries"
27-
29+ assert_operator log_entries . length , :>= , 3 , "Should have at least 3 log entries"
30+
2831 # Find the structured log entry
2932 structured_entry = log_entries . find { |entry | entry [ "msg" ] == "Structured log message" }
33+
3034 assert structured_entry , "Should have a structured log entry"
3135 assert_equal "app" , structured_entry [ "src" ] , "Should have correct source"
3236 assert_equal "info" , structured_entry [ "lvl" ] , "Should have correct level"
33-
37+
3438 # Check that emails are scrubbed
3539 email_log = log_entries . find { |entry | entry [ "msg" ] &.include? ( "email" ) }
3640 if email_log && email_log [ "msg" ] . is_a? ( String )
3741 assert_not_includes email_log [ "msg" ] , "test@example.com" , "Email should be scrubbed"
3842 assert_includes email_log [ "msg" ] , "[EMAIL]" , "Email should be replaced with [EMAIL]"
3943 end
4044 end
41-
45+
4246 test "error logging produces structured error logs" do
4347 get "/logging/error"
48+
4449 assert_response :success
45-
50+
4651 # Parse the logs to verify structured format
4752 log_entries = parse_log_entries
48-
53+
4954 # Find the exception log entries
5055 exception_entries = log_entries . select { |entry | entry [ "evt" ] == "exception" }
51- assert exception_entries . length >= 1 , "Should have at least one exception log entry"
52-
56+
57+ assert_operator exception_entries . length , :>= , 1 , "Should have at least one exception log entry"
58+
5359 # Check the structured exception log
5460 exception_entry = exception_entries . find { |entry | entry [ "message" ] == "Structured error log" }
61+
5562 assert exception_entry , "Should have a structured exception log"
5663 assert_equal "StandardError" , exception_entry [ "err_class" ] , "Should have correct error class"
5764 assert_equal "app" , exception_entry [ "src" ] , "Should have correct source"
5865 end
59-
66+
6067 test "model logging works correctly" do
6168 get "/logging/model"
69+
6270 assert_response :success
63-
71+
6472 # Parse the logs to verify structured format
6573 log_entries = parse_log_entries
66-
74+
6775 # Check model log entries
68- assert log_entries . any? { |entry | entry [ "msg" ] &.include? ( "Created user" ) } ,
76+ assert log_entries . any? { |entry | entry [ "msg" ] &.include? ( "Created user" ) } ,
6977 "Should have a log entry for user creation"
70-
78+
7179 # Check the response
7280 response_json = JSON . parse ( response . body )
81+
7382 assert response_json [ "user_id" ] , "Response should include user_id"
7483 end
75-
84+
7685 test "job logging works correctly" do
7786 # Capture logs during job enqueue and execution
7887 get "/logging/job"
88+
7989 assert_response :success
80-
90+
8191 # Parse the logs to verify job enqueue log
8292 log_entries = parse_log_entries
83-
93+
8494 # Check that the job was enqueued
85- assert log_entries . any? { |entry | entry [ "msg" ] &.include? ( "Job enqueued" ) } ,
95+ assert log_entries . any? { |entry | entry [ "msg" ] &.include? ( "Job enqueued" ) } ,
8696 "Should have a log entry for job enqueue"
87-
97+
8898 # For job execution, we'd need to run the job synchronously or wait for it
8999 # in a real setup. For this test, we'll just check the response.
90100 response_json = JSON . parse ( response . body )
101+
91102 assert response_json [ "job_id" ] , "Response should include job_id"
92103 end
93-
104+
94105 test "structured logging works correctly" do
95106 get "/logging/structured"
107+
96108 assert_response :success
97-
109+
98110 # Parse the logs to verify structured format
99111 log_entries = parse_log_entries
100-
112+
101113 # Check for HTTP log entry
102114 http_entry = log_entries . find { |entry | entry [ "evt" ] == "http_request" }
115+
103116 assert http_entry , "Should have an HTTP request log entry"
104117 assert_equal "GET" , http_entry [ "method" ] , "Should have correct HTTP method"
105118 assert_equal "/logging/structured" , http_entry [ "path" ] , "Should have correct path"
106119 assert_equal 200 , http_entry [ "status" ] , "Should have correct status"
107-
120+
108121 # Check for structured exception log
109- exception_entry = log_entries . find { |entry |
122+ exception_entry = log_entries . find { |entry |
110123 entry [ "evt" ] == "exception" && entry [ "message" ] == "Structured exception log example"
111124 }
125+
112126 assert exception_entry , "Should have a structured exception log example"
113127 assert_equal "RuntimeError" , exception_entry [ "err_class" ] , "Should have correct error class"
114128 end
115-
129+
116130 test "context and tagging works correctly" do
117131 get "/logging/context"
132+
118133 assert_response :success
119-
134+
120135 # Parse the logs to verify structured format
121136 log_entries = parse_log_entries
122-
137+
123138 # Check for tags in log entries
124139 tagged_entries = log_entries . select { |entry | entry [ "tags" ] }
125- assert tagged_entries . any? , "Should have at least one tagged log entry"
126-
140+
141+ assert_predicate tagged_entries , :any? , "Should have at least one tagged log entry"
142+
127143 # Find entry with specific tags
128- entry_with_all_tags = tagged_entries . find { |entry |
129- entry [ "tags" ] &.include? ( "REQUEST_ID_123" ) &&
130- entry [ "tags" ] & .include? ( "USER_456" )
144+ entry_with_all_tags = tagged_entries . find { |entry |
145+ entry [ "tags" ] &.include? ( "REQUEST_ID_123" ) &&
146+ entry [ "tags" ] . include? ( "USER_456" )
131147 }
148+
132149 assert entry_with_all_tags , "Should have a log entry with all specified tags"
133-
150+
134151 # Find entry with nested tags
135- nested_entry = tagged_entries . find { |entry |
152+ nested_entry = tagged_entries . find { |entry |
136153 entry [ "tags" ] &.include? ( "NESTED" )
137154 }
155+
138156 assert nested_entry , "Should have a log entry with nested tag"
139157 assert_equal "warn" , nested_entry [ "lvl" ] , "Nested tagged message should be a warning"
140158 end
141159
142160 private
143-
161+
144162 def parse_log_entries
145163 log_lines = @log_output . string . split ( "\n " )
146- log_lines . map do |line |
147- begin
148- JSON . parse ( line )
149- rescue JSON ::ParserError
150- nil
151- end
152- end . compact
164+ log_lines . filter_map do |line |
165+ JSON . parse ( line )
166+ rescue JSON ::ParserError
167+ nil
168+ end
153169 end
154- end
170+ end
0 commit comments