@joystick.js/db-canary 0.0.0-canary.2209
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.build/getFilesToBuild.js +26 -0
- package/.build/getPlatformSafeFilePath.js +6 -0
- package/.build/getPlatformSafePath.js +6 -0
- package/.build/index.js +88 -0
- package/.build/isWindows.js +3 -0
- package/API_KEY +1 -0
- package/README.md +1821 -0
- package/data/data.mdb +0 -0
- package/data/lock.mdb +0 -0
- package/dist/client/database.js +1 -0
- package/dist/client/index.js +1 -0
- package/dist/server/cluster/index.js +1 -0
- package/dist/server/cluster/master.js +20 -0
- package/dist/server/cluster/worker.js +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/lib/api_key_manager.js +9 -0
- package/dist/server/lib/auth_manager.js +1 -0
- package/dist/server/lib/auto_index_manager.js +1 -0
- package/dist/server/lib/backup_manager.js +1 -0
- package/dist/server/lib/connection_manager.js +1 -0
- package/dist/server/lib/disk_utils.js +2 -0
- package/dist/server/lib/http_server.js +405 -0
- package/dist/server/lib/index_manager.js +1 -0
- package/dist/server/lib/load_settings.js +1 -0
- package/dist/server/lib/logger.js +1 -0
- package/dist/server/lib/op_types.js +1 -0
- package/dist/server/lib/operation_dispatcher.js +1 -0
- package/dist/server/lib/operations/admin.js +1 -0
- package/dist/server/lib/operations/bulk_write.js +1 -0
- package/dist/server/lib/operations/create_index.js +1 -0
- package/dist/server/lib/operations/delete_one.js +1 -0
- package/dist/server/lib/operations/drop_index.js +1 -0
- package/dist/server/lib/operations/find.js +1 -0
- package/dist/server/lib/operations/find_one.js +1 -0
- package/dist/server/lib/operations/get_indexes.js +1 -0
- package/dist/server/lib/operations/insert_one.js +1 -0
- package/dist/server/lib/operations/update_one.js +1 -0
- package/dist/server/lib/performance_monitor.js +1 -0
- package/dist/server/lib/query_engine.js +1 -0
- package/dist/server/lib/recovery_manager.js +1 -0
- package/dist/server/lib/replication_manager.js +1 -0
- package/dist/server/lib/safe_json_parse.js +1 -0
- package/dist/server/lib/send_response.js +1 -0
- package/dist/server/lib/tcp_protocol.js +1 -0
- package/dist/server/lib/write_forwarder.js +1 -0
- package/dist/server/lib/write_queue.js +1 -0
- package/increment_version.js +3 -0
- package/logs/.013e15b54597d05db4b4b53ecc37b10c92a72927-audit.json +20 -0
- package/logs/.02de550a67ea0f5961faa2dfd458a4d06f59ebd1-audit.json +20 -0
- package/logs/.03494ba24eb3c72214b4068a77d54b8993bee651-audit.json +20 -0
- package/logs/.06309ec60b339be1259a7993dd09c732f8907fbc-audit.json +20 -0
- package/logs/.0663a04dcfa17285661e5e1b8cfa51f41523b210-audit.json +20 -0
- package/logs/.0f06e6c4c9b824622729e13927587479e5060391-audit.json +20 -0
- package/logs/.16ccf58682ecb22b3e3ec63f0da1b7fe9be56528-audit.json +20 -0
- package/logs/.1fa1a5d02f496474b1ab473524c65c984146a9ad-audit.json +20 -0
- package/logs/.2223c0ae3bea6f0d62c62b1d319cc8634856abb7-audit.json +20 -0
- package/logs/.23dc79ffda3e083665e6f5993f59397adcbf4a46-audit.json +20 -0
- package/logs/.28104f49b03906b189eefd1cd462cb46c3c0af22-audit.json +20 -0
- package/logs/.29cdbf13808abe6a0ce70ee2f2efdd680ce3fd8e-audit.json +20 -0
- package/logs/.2a9889afd071f77f41f5170d08703a0afca866b7-audit.json +20 -0
- package/logs/.2acec3d1940a2bbed487528b703ee5948959a599-audit.json +20 -0
- package/logs/.2fb60ff326338c02bfedbcd0e936444e4a216750-audit.json +20 -0
- package/logs/.318fc7a19530d76a345f030f7cad00dda15300e7-audit.json +20 -0
- package/logs/.3cf27043e19085f908cedc7701e6d013463208ee-audit.json +25 -0
- package/logs/.3d90d785415817fc443402843b7c95f8371adc9b-audit.json +20 -0
- package/logs/.4074bca620375f72966fc52dfd439577727671e5-audit.json +20 -0
- package/logs/.40eecf018417ea80a70ea8ec7a3cc9406bc6334b-audit.json +20 -0
- package/logs/.50e974f1ef7c365fca6a1251b2e2c2252914cb5e-audit.json +20 -0
- package/logs/.52cb7d9e4223cf26ba36006ac26b949a97c7923c-audit.json +20 -0
- package/logs/.54befcdb84c15aad980705a31bcc9f555c3577ab-audit.json +20 -0
- package/logs/.57dfb70e22eddb84db2e3c0ceeefac5c0b9baffa-audit.json +20 -0
- package/logs/.5f0b24705a1eaad4eca4968f2d86f91b3f9be683-audit.json +20 -0
- package/logs/.61ba98fdda7db58576b382fee07904e5db1169d6-audit.json +20 -0
- package/logs/.6235017727ef6b199d569a99d6aa8c8e80a1b475-audit.json +20 -0
- package/logs/.63db16193699219489d218a1ddea5dde3750cae4-audit.json +20 -0
- package/logs/.64fb67dfe14149c9eef728d79bf30a54da809c60-audit.json +20 -0
- package/logs/.669137453368987c1f311b5345342527afb54e50-audit.json +20 -0
- package/logs/.7a71f8c89ea28ae266d356aeff6306e876a30fbb-audit.json +20 -0
- package/logs/.7afbaa90fe9dc3a7d682676f9bb79f9a1b1fd9a6-audit.json +20 -0
- package/logs/.7ca29e322cd05327035de850099e7610864f2347-audit.json +20 -0
- package/logs/.83335ab3347e449dae03455a110aaf7f120d4802-audit.json +20 -0
- package/logs/.8c2487b5fd445d2c8e5c483c80b9fa99bbf1ca58-audit.json +20 -0
- package/logs/.8c8b9dc386922c9f3b4c13251af7052aac1d24c0-audit.json +20 -0
- package/logs/.8d6155d94640c4863301ae0fee5e4e7372a21446-audit.json +20 -0
- package/logs/.944a3119a243deea7c8270d5d9e582bb1d0eaa10-audit.json +20 -0
- package/logs/.9816a845c30fb2909f3b26a23eeb3538ebcad5db-audit.json +20 -0
- package/logs/.9dc08784e38b865488177c26d4af5934555e0323-audit.json +20 -0
- package/logs/.9dd27d2e0e454ac0a37600206d1cac5493b0d7ee-audit.json +20 -0
- package/logs/.a3d486feeac7654c59b547de96600e8849a06d4f-audit.json +20 -0
- package/logs/.a5b811f4def22250f86cc18870d7c4573625df22-audit.json +20 -0
- package/logs/.a61648eb5f830e0b6f508ac35e4f8f629d2ad4c7-audit.json +20 -0
- package/logs/.a89016d507045771b4b5a65656944a9c0f1e528b-audit.json +20 -0
- package/logs/.a99bee160a1c590be959af46bacc02724803f691-audit.json +20 -0
- package/logs/.ada7906d6243fd7da802f03d86c4ae5dd9df6236-audit.json +20 -0
- package/logs/.b518339ee942143b6af983af167f5bbb6983b4de-audit.json +20 -0
- package/logs/.b51b124b166d53c9519017856ea610d61d65fabe-audit.json +20 -0
- package/logs/.b7a6aee19f58e55633d5e4a3709041c47dfff975-audit.json +20 -0
- package/logs/.bd7a8a6ba9c55d557a4867ab53f02e3ec2e1553d-audit.json +20 -0
- package/logs/.c1435dafe453b169d6392b25065f3cf4ab6fbb21-audit.json +20 -0
- package/logs/.c17e1ce043109f77dc2f0e2aa290a9d1ed842c03-audit.json +20 -0
- package/logs/.ca62637ce9540e5a38a2fbedb2115febb6ad308a-audit.json +15 -0
- package/logs/.ccee67b9c176967f8977071409a41f5cb5cd6ad4-audit.json +20 -0
- package/logs/.db24043417ea79a6f14cd947476399e53930b48d-audit.json +20 -0
- package/logs/.e0f12acccb57829f5f33712bb2e2607ecd808147-audit.json +20 -0
- package/logs/.e9b6cc33d0bbd2e644c4e2bf44d177f850016557-audit.json +20 -0
- package/logs/.f15291d434808e3bdca7963ccd2e73893be027e6-audit.json +20 -0
- package/logs/.f4bdf9e21ef84f8a3fae3ffb32bbc39275991351-audit.json +15 -0
- package/logs/.fbac3aefac1e81b4230df5aa50667cb90d51024f-audit.json +20 -0
- package/logs/.fcfd495c0a9169db243f4a4f21878ee02b76413c-audit.json +20 -0
- package/logs/admin-2025-09-12.log +580 -0
- package/logs/admin-2025-09-15.log +283 -0
- package/logs/admin-error-2025-09-12.log +22 -0
- package/logs/admin-error-2025-09-15.log +10 -0
- package/logs/api_key_manager-2025-09-12.log +658 -0
- package/logs/api_key_manager-2025-09-15.log +295 -0
- package/logs/api_key_manager-error-2025-09-12.log +0 -0
- package/logs/api_key_manager-error-2025-09-15.log +0 -0
- package/logs/auth_manager-2025-09-12.log +4432 -0
- package/logs/auth_manager-2025-09-15.log +2000 -0
- package/logs/auth_manager-error-2025-09-12.log +11 -0
- package/logs/auth_manager-error-2025-09-15.log +5 -0
- package/logs/auto_index_manager-2025-09-12.log +84 -0
- package/logs/auto_index_manager-2025-09-15.log +45 -0
- package/logs/auto_index_manager-error-2025-09-12.log +6 -0
- package/logs/auto_index_manager-error-2025-09-15.log +0 -0
- package/logs/backup_manager-2025-09-12.log +198 -0
- package/logs/backup_manager-2025-09-15.log +90 -0
- package/logs/backup_manager-error-2025-09-12.log +198 -0
- package/logs/backup_manager-error-2025-09-15.log +90 -0
- package/logs/bulk_write-2025-09-12.log +66 -0
- package/logs/bulk_write-2025-09-15.log +38 -0
- package/logs/bulk_write-error-2025-09-12.log +0 -0
- package/logs/bulk_write-error-2025-09-15.log +0 -0
- package/logs/connection_manager-2025-09-12.log +2412 -0
- package/logs/connection_manager-2025-09-15.log +1132 -0
- package/logs/connection_manager-error-2025-09-12.log +0 -0
- package/logs/connection_manager-error-2025-09-15.log +0 -0
- package/logs/create_index-2025-09-12.log +302 -0
- package/logs/create_index-2025-09-15.log +158 -0
- package/logs/create_index-error-2025-09-12.log +30 -0
- package/logs/create_index-error-2025-09-15.log +13 -0
- package/logs/delete_one-2025-09-12.log +73 -0
- package/logs/delete_one-2025-09-15.log +43 -0
- package/logs/delete_one-error-2025-09-12.log +0 -0
- package/logs/delete_one-error-2025-09-15.log +0 -0
- package/logs/disk_utils-2025-09-12.log +4954 -0
- package/logs/disk_utils-2025-09-15.log +2446 -0
- package/logs/disk_utils-error-2025-09-12.log +0 -0
- package/logs/disk_utils-error-2025-09-15.log +0 -0
- package/logs/drop_index-2025-09-12.log +41 -0
- package/logs/drop_index-2025-09-15.log +23 -0
- package/logs/drop_index-error-2025-09-12.log +11 -0
- package/logs/drop_index-error-2025-09-15.log +5 -0
- package/logs/find-2025-09-12.log +1050 -0
- package/logs/find-2025-09-15.log +592 -0
- package/logs/find-error-2025-09-12.log +1 -0
- package/logs/find-error-2025-09-15.log +0 -0
- package/logs/find_one-2025-09-12.log +425 -0
- package/logs/find_one-2025-09-15.log +264 -0
- package/logs/find_one-error-2025-09-12.log +5 -0
- package/logs/find_one-error-2025-09-15.log +0 -0
- package/logs/get_indexes-2025-09-12.log +84 -0
- package/logs/get_indexes-2025-09-15.log +56 -0
- package/logs/get_indexes-error-2025-09-12.log +6 -0
- package/logs/get_indexes-error-2025-09-15.log +0 -0
- package/logs/http_server-2025-09-12.log +2772 -0
- package/logs/http_server-2025-09-15.log +1276 -0
- package/logs/http_server-error-2025-09-12.log +212 -0
- package/logs/http_server-error-2025-09-15.log +44 -0
- package/logs/index_manager-2025-09-12.log +5031 -0
- package/logs/index_manager-2025-09-15.log +2909 -0
- package/logs/index_manager-error-2025-09-12.log +80 -0
- package/logs/index_manager-error-2025-09-15.log +38 -0
- package/logs/insert_one-2025-09-12.log +2181 -0
- package/logs/insert_one-2025-09-15.log +1293 -0
- package/logs/insert_one-error-2025-09-12.log +0 -0
- package/logs/insert_one-error-2025-09-15.log +0 -0
- package/logs/master-2025-09-12.log +1882 -0
- package/logs/master-2025-09-15.log +910 -0
- package/logs/master-error-2025-09-12.log +80 -0
- package/logs/master-error-2025-09-15.log +0 -0
- package/logs/operation_dispatcher-2025-09-12.log +751 -0
- package/logs/operation_dispatcher-2025-09-15.log +359 -0
- package/logs/operation_dispatcher-error-2025-09-12.log +33 -0
- package/logs/operation_dispatcher-error-2025-09-15.log +11 -0
- package/logs/performance_monitor-2025-09-12.log +14889 -0
- package/logs/performance_monitor-2025-09-15.log +6803 -0
- package/logs/performance_monitor-error-2025-09-12.log +0 -0
- package/logs/performance_monitor-error-2025-09-15.log +0 -0
- package/logs/query_engine-2025-09-12.log +5310 -0
- package/logs/query_engine-2025-09-15.log +2639 -0
- package/logs/query_engine-error-2025-09-12.log +0 -0
- package/logs/query_engine-error-2025-09-15.log +0 -0
- package/logs/recovery_manager-2025-09-12.log +462 -0
- package/logs/recovery_manager-2025-09-15.log +210 -0
- package/logs/recovery_manager-error-2025-09-12.log +22 -0
- package/logs/recovery_manager-error-2025-09-15.log +10 -0
- package/logs/replication-2025-09-12.log +1923 -0
- package/logs/replication-2025-09-15.log +917 -0
- package/logs/replication-error-2025-09-12.log +33 -0
- package/logs/replication-error-2025-09-15.log +15 -0
- package/logs/server-2025-09-12.log +2601 -0
- package/logs/server-2025-09-15.log +1191 -0
- package/logs/server-error-2025-09-12.log +0 -0
- package/logs/server-error-2025-09-15.log +0 -0
- package/logs/tcp_protocol-2025-09-12.log +22 -0
- package/logs/tcp_protocol-2025-09-15.log +10 -0
- package/logs/tcp_protocol-error-2025-09-12.log +22 -0
- package/logs/tcp_protocol-error-2025-09-15.log +10 -0
- package/logs/test-2025-09-12.log +0 -0
- package/logs/test-2025-09-15.log +0 -0
- package/logs/test-error-2025-09-12.log +0 -0
- package/logs/test-error-2025-09-15.log +0 -0
- package/logs/update_one-2025-09-12.log +173 -0
- package/logs/update_one-2025-09-15.log +118 -0
- package/logs/update_one-error-2025-09-12.log +0 -0
- package/logs/update_one-error-2025-09-15.log +0 -0
- package/logs/worker-2025-09-12.log +1457 -0
- package/logs/worker-2025-09-15.log +695 -0
- package/logs/worker-error-2025-09-12.log +0 -0
- package/logs/worker-error-2025-09-15.log +0 -0
- package/logs/write_forwarder-2025-09-12.log +1956 -0
- package/logs/write_forwarder-2025-09-15.log +932 -0
- package/logs/write_forwarder-error-2025-09-12.log +66 -0
- package/logs/write_forwarder-error-2025-09-15.log +30 -0
- package/logs/write_queue-2025-09-12.log +612 -0
- package/logs/write_queue-2025-09-15.log +301 -0
- package/logs/write_queue-error-2025-09-12.log +184 -0
- package/logs/write_queue-error-2025-09-15.log +83 -0
- package/package.json +48 -0
- package/prompts/01-core-infrastructure.md +56 -0
- package/prompts/02-secondary-indexing.md +65 -0
- package/prompts/03-write-serialization.md +63 -0
- package/prompts/04-enhanced-authentication.md +75 -0
- package/prompts/05-comprehensive-admin-operations.md +75 -0
- package/prompts/06-backup-and-restore-system.md +106 -0
- package/prompts/07-production-safety-features.md +107 -0
- package/prompts/08-tcp-client-library.md +121 -0
- package/prompts/09-api-method-chaining.md +134 -0
- package/prompts/10-automatic-index-creation.md +223 -0
- package/prompts/11-operation-naming-consistency.md +268 -0
- package/prompts/12-tcp-replication-system.md +333 -0
- package/prompts/13-master-read-write-operations.md +57 -0
- package/prompts/14-index-upsert-operations.md +68 -0
- package/prompts/15-client-api-return-types.md +81 -0
- package/prompts/16-server-setup-ui.md +97 -0
- package/prompts/17-emergency-password-change.md +108 -0
- package/prompts/18-joystick-framework-integration.md +116 -0
- package/prompts/19-api-key-authentication-system.md +137 -0
- package/prompts/20-configurable-server-port.md +105 -0
- package/prompts/21-multi-database-support.md +161 -0
- package/prompts/FULL_TEXT_SEARCH.md +293 -0
- package/prompts/PROMPTS.md +158 -0
- package/prompts/README.md +221 -0
- package/prompts/TYPESCRIPT_GENERATION.md +179 -0
- package/src/client/database.js +166 -0
- package/src/client/index.js +752 -0
- package/src/server/cluster/index.js +53 -0
- package/src/server/cluster/master.js +774 -0
- package/src/server/cluster/worker.js +537 -0
- package/src/server/index.js +540 -0
- package/src/server/lib/api_key_manager.js +473 -0
- package/src/server/lib/auth_manager.js +375 -0
- package/src/server/lib/auto_index_manager.js +681 -0
- package/src/server/lib/backup_manager.js +650 -0
- package/src/server/lib/connection_manager.js +218 -0
- package/src/server/lib/disk_utils.js +118 -0
- package/src/server/lib/http_server.js +1165 -0
- package/src/server/lib/index_manager.js +756 -0
- package/src/server/lib/load_settings.js +143 -0
- package/src/server/lib/logger.js +135 -0
- package/src/server/lib/op_types.js +29 -0
- package/src/server/lib/operation_dispatcher.js +268 -0
- package/src/server/lib/operations/admin.js +808 -0
- package/src/server/lib/operations/bulk_write.js +367 -0
- package/src/server/lib/operations/create_index.js +68 -0
- package/src/server/lib/operations/delete_one.js +114 -0
- package/src/server/lib/operations/drop_index.js +58 -0
- package/src/server/lib/operations/find.js +340 -0
- package/src/server/lib/operations/find_one.js +319 -0
- package/src/server/lib/operations/get_indexes.js +52 -0
- package/src/server/lib/operations/insert_one.js +113 -0
- package/src/server/lib/operations/update_one.js +225 -0
- package/src/server/lib/performance_monitor.js +313 -0
- package/src/server/lib/query_engine.js +243 -0
- package/src/server/lib/recovery_manager.js +388 -0
- package/src/server/lib/replication_manager.js +727 -0
- package/src/server/lib/safe_json_parse.js +21 -0
- package/src/server/lib/send_response.js +47 -0
- package/src/server/lib/tcp_protocol.js +130 -0
- package/src/server/lib/write_forwarder.js +636 -0
- package/src/server/lib/write_queue.js +335 -0
- package/test_data/data.mdb +0 -0
- package/test_data/lock.mdb +0 -0
- package/tests/client/index.test.js +1232 -0
- package/tests/server/cluster/cluster.test.js +248 -0
- package/tests/server/cluster/master_read_write_operations.test.js +577 -0
- package/tests/server/index.test.js +651 -0
- package/tests/server/integration/authentication_integration.test.js +294 -0
- package/tests/server/integration/auto_indexing_integration.test.js +268 -0
- package/tests/server/integration/backup_integration.test.js +513 -0
- package/tests/server/integration/indexing_integration.test.js +126 -0
- package/tests/server/integration/production_safety_integration.test.js +358 -0
- package/tests/server/integration/replication_integration.test.js +227 -0
- package/tests/server/integration/write_serialization_integration.test.js +246 -0
- package/tests/server/lib/api_key_manager.test.js +516 -0
- package/tests/server/lib/auth_manager.test.js +317 -0
- package/tests/server/lib/auto_index_manager.test.js +275 -0
- package/tests/server/lib/backup_manager.test.js +238 -0
- package/tests/server/lib/connection_manager.test.js +221 -0
- package/tests/server/lib/disk_utils.test.js +63 -0
- package/tests/server/lib/http_server.test.js +389 -0
- package/tests/server/lib/index_manager.test.js +301 -0
- package/tests/server/lib/load_settings.test.js +107 -0
- package/tests/server/lib/load_settings_port_config.test.js +243 -0
- package/tests/server/lib/logger.test.js +282 -0
- package/tests/server/lib/operations/admin.test.js +638 -0
- package/tests/server/lib/operations/bulk_write.test.js +128 -0
- package/tests/server/lib/operations/create_index.test.js +138 -0
- package/tests/server/lib/operations/delete_one.test.js +52 -0
- package/tests/server/lib/operations/drop_index.test.js +72 -0
- package/tests/server/lib/operations/find.test.js +93 -0
- package/tests/server/lib/operations/find_one.test.js +91 -0
- package/tests/server/lib/operations/get_indexes.test.js +87 -0
- package/tests/server/lib/operations/insert_one.test.js +42 -0
- package/tests/server/lib/operations/update_one.test.js +89 -0
- package/tests/server/lib/performance_monitor.test.js +185 -0
- package/tests/server/lib/query_engine.test.js +46 -0
- package/tests/server/lib/recovery_manager.test.js +414 -0
- package/tests/server/lib/replication_manager.test.js +202 -0
- package/tests/server/lib/safe_json_parse.test.js +45 -0
- package/tests/server/lib/send_response.test.js +155 -0
- package/tests/server/lib/tcp_protocol.test.js +169 -0
- package/tests/server/lib/write_forwarder.test.js +258 -0
- package/tests/server/lib/write_queue.test.js +255 -0
- package/tsconfig.json +30 -0
- package/types/client/index.d.ts +447 -0
- package/types/server/cluster/index.d.ts +28 -0
- package/types/server/cluster/master.d.ts +115 -0
- package/types/server/cluster/worker.d.ts +1 -0
- package/types/server/lib/auth_manager.d.ts +13 -0
- package/types/server/lib/backup_manager.d.ts +43 -0
- package/types/server/lib/connection_manager.d.ts +15 -0
- package/types/server/lib/disk_utils.d.ts +3 -0
- package/types/server/lib/index_manager.d.ts +24 -0
- package/types/server/lib/load_settings.d.ts +4 -0
- package/types/server/lib/logger.d.ts +44 -0
- package/types/server/lib/op_types.d.ts +6 -0
- package/types/server/lib/performance_monitor.d.ts +68 -0
- package/types/server/lib/query_engine.d.ts +10 -0
- package/types/server/lib/safe_json_parse.d.ts +7 -0
- package/types/server/lib/send_response.d.ts +3 -0
- package/types/server/lib/tcp_protocol.d.ts +12 -0
- package/types/server/lib/write_queue.d.ts +2 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { load_settings, get_settings, reload_settings, clear_settings_cache } from '../../../src/server/lib/load_settings.js';
|
|
3
|
+
|
|
4
|
+
const valid_settings = {
|
|
5
|
+
authentication: {
|
|
6
|
+
password_hash: '$2b$10$example.hash.here'
|
|
7
|
+
},
|
|
8
|
+
database: {
|
|
9
|
+
max_connections: 100
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
test.beforeEach(() => {
|
|
14
|
+
// NOTE: Clean up any cached settings and environment variables before each test.
|
|
15
|
+
clear_settings_cache();
|
|
16
|
+
delete process.env.JOYSTICK_DB_SETTINGS;
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
test.afterEach(() => {
|
|
20
|
+
// NOTE: Clean up environment variables after each test.
|
|
21
|
+
delete process.env.JOYSTICK_DB_SETTINGS;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
test('load_settings loads valid JSON from environment variable', (t) => {
|
|
25
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(valid_settings);
|
|
26
|
+
|
|
27
|
+
const settings = load_settings();
|
|
28
|
+
|
|
29
|
+
t.deepEqual(settings, valid_settings);
|
|
30
|
+
t.is(settings.authentication.password_hash, '$2b$10$example.hash.here');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
test('load_settings throws error for missing environment variable', (t) => {
|
|
34
|
+
const error = t.throws(() => {
|
|
35
|
+
load_settings();
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
t.true(error.message.includes('JOYSTICK_DB_SETTINGS environment variable is not set'));
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
test('load_settings throws error for invalid JSON in environment variable', (t) => {
|
|
42
|
+
process.env.JOYSTICK_DB_SETTINGS = '{ invalid json }';
|
|
43
|
+
|
|
44
|
+
const error = t.throws(() => {
|
|
45
|
+
load_settings();
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
t.true(error.message.includes('Invalid JSON in JOYSTICK_DB_SETTINGS environment variable'));
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
test('get_settings returns cached settings', (t) => {
|
|
52
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(valid_settings);
|
|
53
|
+
|
|
54
|
+
load_settings();
|
|
55
|
+
const settings = get_settings();
|
|
56
|
+
|
|
57
|
+
t.deepEqual(settings, valid_settings);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('get_settings throws error when settings not loaded', (t) => {
|
|
61
|
+
const error = t.throws(() => {
|
|
62
|
+
get_settings();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
t.true(error.message.includes('Settings not loaded'));
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('reload_settings reloads from environment variable', (t) => {
|
|
69
|
+
const initial_settings = { test: 'initial' };
|
|
70
|
+
const updated_settings = { test: 'updated' };
|
|
71
|
+
|
|
72
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(initial_settings);
|
|
73
|
+
load_settings();
|
|
74
|
+
|
|
75
|
+
t.deepEqual(get_settings(), initial_settings);
|
|
76
|
+
|
|
77
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(updated_settings);
|
|
78
|
+
const reloaded = reload_settings();
|
|
79
|
+
|
|
80
|
+
t.deepEqual(reloaded, updated_settings);
|
|
81
|
+
t.deepEqual(get_settings(), updated_settings);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
test('load_settings works with complex nested settings', (t) => {
|
|
85
|
+
const complex_settings = {
|
|
86
|
+
authentication: {
|
|
87
|
+
password_hash: '$2b$10$example.hash.here',
|
|
88
|
+
created_at: '2023-01-01T00:00:00.000Z',
|
|
89
|
+
failed_attempts: {},
|
|
90
|
+
rate_limits: {}
|
|
91
|
+
},
|
|
92
|
+
database: {
|
|
93
|
+
max_connections: 100,
|
|
94
|
+
timeout: 5000
|
|
95
|
+
},
|
|
96
|
+
cluster: {
|
|
97
|
+
enabled: true,
|
|
98
|
+
nodes: ['node1', 'node2']
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
|
|
102
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify(complex_settings);
|
|
103
|
+
|
|
104
|
+
const settings = load_settings();
|
|
105
|
+
|
|
106
|
+
t.deepEqual(settings, complex_settings);
|
|
107
|
+
});
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import { load_settings, get_settings, get_port_configuration, clear_settings_cache } from '../../../src/server/lib/load_settings.js';
|
|
3
|
+
|
|
4
|
+
test.beforeEach(() => {
|
|
5
|
+
// Clean up environment variables before each test
|
|
6
|
+
delete process.env.JOYSTICK_DB_SETTINGS;
|
|
7
|
+
clear_settings_cache();
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
test.afterEach(() => {
|
|
11
|
+
// Clean up environment variables after each test
|
|
12
|
+
delete process.env.JOYSTICK_DB_SETTINGS;
|
|
13
|
+
clear_settings_cache();
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test('get_port_configuration returns default ports when no settings', (t) => {
|
|
17
|
+
const { tcp_port, http_port } = get_port_configuration();
|
|
18
|
+
|
|
19
|
+
t.is(tcp_port, 1983);
|
|
20
|
+
t.is(http_port, 1984);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test('get_port_configuration uses configured port from settings', (t) => {
|
|
24
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
25
|
+
port: 3000,
|
|
26
|
+
authentication: {}
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const { tcp_port, http_port } = get_port_configuration();
|
|
30
|
+
|
|
31
|
+
t.is(tcp_port, 3000);
|
|
32
|
+
t.is(http_port, 3001);
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('load_settings validates port configuration - valid port', (t) => {
|
|
36
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
37
|
+
port: 2000,
|
|
38
|
+
authentication: {}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
t.notThrows(() => {
|
|
42
|
+
load_settings();
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
const settings = get_settings();
|
|
46
|
+
t.is(settings.port, 2000);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
test('load_settings validates port configuration - port too low', (t) => {
|
|
50
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
51
|
+
port: 1023,
|
|
52
|
+
authentication: {}
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
const error = t.throws(() => {
|
|
56
|
+
load_settings();
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
t.true(error.message.includes('Port must be between 1024 and 65534'));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test('load_settings validates port configuration - port too high', (t) => {
|
|
63
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
64
|
+
port: 70000,
|
|
65
|
+
authentication: {}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
const error = t.throws(() => {
|
|
69
|
+
load_settings();
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
t.true(error.message.includes('HTTP port (70001) would exceed maximum port number'));
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
test('load_settings validates port configuration - HTTP port overflow', (t) => {
|
|
76
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
77
|
+
port: 65535,
|
|
78
|
+
authentication: {}
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
const error = t.throws(() => {
|
|
82
|
+
load_settings();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
t.true(error.message.includes('HTTP port (65536) would exceed maximum port number'));
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
test('load_settings validates port configuration - non-integer port', (t) => {
|
|
89
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
90
|
+
port: 1983.5,
|
|
91
|
+
authentication: {}
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
const error = t.throws(() => {
|
|
95
|
+
load_settings();
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
t.true(error.message.includes('Port must be an integer'));
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
test('load_settings validates port configuration - string port', (t) => {
|
|
102
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
103
|
+
port: "1983",
|
|
104
|
+
authentication: {}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const error = t.throws(() => {
|
|
108
|
+
load_settings();
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
t.true(error.message.includes('Port must be an integer'));
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
test('load_settings allows valid port range - minimum valid port', (t) => {
|
|
115
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
116
|
+
port: 1024,
|
|
117
|
+
authentication: {}
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
t.notThrows(() => {
|
|
121
|
+
load_settings();
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const settings = get_settings();
|
|
125
|
+
t.is(settings.port, 1024);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test('load_settings allows valid port range - maximum valid port', (t) => {
|
|
129
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
130
|
+
port: 65534,
|
|
131
|
+
authentication: {}
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
t.notThrows(() => {
|
|
135
|
+
load_settings();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
const settings = get_settings();
|
|
139
|
+
t.is(settings.port, 65534);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('load_settings allows settings without port configuration', (t) => {
|
|
143
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
144
|
+
authentication: {},
|
|
145
|
+
s3: { bucket: 'test' }
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
t.notThrows(() => {
|
|
149
|
+
load_settings();
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
const settings = get_settings();
|
|
153
|
+
t.is(settings.port, undefined);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test('get_port_configuration handles mixed settings scenarios', (t) => {
|
|
157
|
+
// Test with settings that don't include port
|
|
158
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
159
|
+
authentication: {},
|
|
160
|
+
s3: { bucket: 'test' }
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const { tcp_port, http_port } = get_port_configuration();
|
|
164
|
+
|
|
165
|
+
t.is(tcp_port, 1983);
|
|
166
|
+
t.is(http_port, 1984);
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('port configuration works with complex settings', (t) => {
|
|
170
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
171
|
+
port: 5000,
|
|
172
|
+
authentication: {
|
|
173
|
+
password_hash: 'test-hash'
|
|
174
|
+
},
|
|
175
|
+
s3: {
|
|
176
|
+
bucket: 'test-bucket',
|
|
177
|
+
region: 'us-east-1'
|
|
178
|
+
},
|
|
179
|
+
replication: {
|
|
180
|
+
enabled: true,
|
|
181
|
+
nodes: ['node1', 'node2']
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
t.notThrows(() => {
|
|
186
|
+
load_settings();
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
const settings = get_settings();
|
|
190
|
+
t.is(settings.port, 5000);
|
|
191
|
+
|
|
192
|
+
const { tcp_port, http_port } = get_port_configuration();
|
|
193
|
+
t.is(tcp_port, 5000);
|
|
194
|
+
t.is(http_port, 5001);
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test('port validation error messages are descriptive', (t) => {
|
|
198
|
+
// Test port too low
|
|
199
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({ port: 500 });
|
|
200
|
+
|
|
201
|
+
let error = t.throws(() => load_settings());
|
|
202
|
+
t.true(error.message.includes('Port must be between 1024 and 65534'));
|
|
203
|
+
t.true(error.message.includes('HTTP port will be port + 1'));
|
|
204
|
+
|
|
205
|
+
clear_settings_cache();
|
|
206
|
+
|
|
207
|
+
// Test HTTP port overflow
|
|
208
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({ port: 65535 });
|
|
209
|
+
|
|
210
|
+
error = t.throws(() => load_settings());
|
|
211
|
+
t.true(error.message.includes('HTTP port (65536) would exceed maximum port number (65535)'));
|
|
212
|
+
t.true(error.message.includes('Use a lower TCP port'));
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
test('get_port_configuration is resilient to settings loading errors', (t) => {
|
|
216
|
+
// Set invalid JSON to cause settings loading to fail
|
|
217
|
+
process.env.JOYSTICK_DB_SETTINGS = '{ invalid json }';
|
|
218
|
+
|
|
219
|
+
// Should not throw and should return defaults
|
|
220
|
+
const { tcp_port, http_port } = get_port_configuration();
|
|
221
|
+
|
|
222
|
+
t.is(tcp_port, 1983);
|
|
223
|
+
t.is(http_port, 1984);
|
|
224
|
+
});
|
|
225
|
+
|
|
226
|
+
test('port configuration updates when settings are reloaded', (t) => {
|
|
227
|
+
// Start with default configuration
|
|
228
|
+
let { tcp_port, http_port } = get_port_configuration();
|
|
229
|
+
t.is(tcp_port, 1983);
|
|
230
|
+
t.is(http_port, 1984);
|
|
231
|
+
|
|
232
|
+
// Set new port configuration
|
|
233
|
+
process.env.JOYSTICK_DB_SETTINGS = JSON.stringify({
|
|
234
|
+
port: 4000,
|
|
235
|
+
authentication: {}
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
// Configuration should update after loading settings
|
|
239
|
+
load_settings();
|
|
240
|
+
({ tcp_port, http_port } = get_port_configuration());
|
|
241
|
+
t.is(tcp_port, 4000);
|
|
242
|
+
t.is(http_port, 4001);
|
|
243
|
+
});
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import sinon from 'sinon';
|
|
3
|
+
import create_logger from '../../../src/server/lib/logger.js';
|
|
4
|
+
|
|
5
|
+
test.beforeEach(t => {
|
|
6
|
+
t.context.mock_logger = {
|
|
7
|
+
info: sinon.stub(),
|
|
8
|
+
warn: sinon.stub(),
|
|
9
|
+
error: sinon.stub(),
|
|
10
|
+
debug: sinon.stub()
|
|
11
|
+
};
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test.afterEach(t => {
|
|
15
|
+
sinon.restore();
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
test('create_logger returns logger and create_context_logger function', t => {
|
|
19
|
+
const result = create_logger('test');
|
|
20
|
+
|
|
21
|
+
t.truthy(result.logger);
|
|
22
|
+
t.is(typeof result.create_context_logger, 'function');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
test('create_logger with different component names', t => {
|
|
26
|
+
const result_one = create_logger('master');
|
|
27
|
+
const result_two = create_logger('worker');
|
|
28
|
+
const result_three = create_logger();
|
|
29
|
+
|
|
30
|
+
t.truthy(result_one.logger);
|
|
31
|
+
t.truthy(result_two.logger);
|
|
32
|
+
t.truthy(result_three.logger);
|
|
33
|
+
t.is(typeof result_one.create_context_logger, 'function');
|
|
34
|
+
t.is(typeof result_two.create_context_logger, 'function');
|
|
35
|
+
t.is(typeof result_three.create_context_logger, 'function');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
test('create_context_logger returns object with logging methods', t => {
|
|
39
|
+
const { create_context_logger } = create_logger('test');
|
|
40
|
+
const context_logger = create_context_logger();
|
|
41
|
+
|
|
42
|
+
t.is(typeof context_logger.info, 'function');
|
|
43
|
+
t.is(typeof context_logger.warn, 'function');
|
|
44
|
+
t.is(typeof context_logger.error, 'function');
|
|
45
|
+
t.is(typeof context_logger.debug, 'function');
|
|
46
|
+
t.is(typeof context_logger.log_operation, 'function');
|
|
47
|
+
t.is(typeof context_logger.log_request, 'function');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
test('context logger info method with base context', t => {
|
|
51
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
52
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
53
|
+
|
|
54
|
+
const base_context = { component: 'test', pid: 123 };
|
|
55
|
+
const context_logger = create_context_logger(base_context);
|
|
56
|
+
|
|
57
|
+
const message = 'Test message';
|
|
58
|
+
const additional_context = { operation: 'test_op' };
|
|
59
|
+
|
|
60
|
+
context_logger.info(message, additional_context);
|
|
61
|
+
|
|
62
|
+
t.true(info_stub.calledOnce);
|
|
63
|
+
const call = info_stub.firstCall;
|
|
64
|
+
t.is(call.args[0], message);
|
|
65
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...additional_context });
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('context logger warn method with context', t => {
|
|
69
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
70
|
+
const warn_stub = sinon.stub(logger, 'warn');
|
|
71
|
+
|
|
72
|
+
const base_context = { component: 'test' };
|
|
73
|
+
const context_logger = create_context_logger(base_context);
|
|
74
|
+
|
|
75
|
+
const message = 'Warning message';
|
|
76
|
+
const additional_context = { warning_type: 'test' };
|
|
77
|
+
|
|
78
|
+
context_logger.warn(message, additional_context);
|
|
79
|
+
|
|
80
|
+
t.true(warn_stub.calledOnce);
|
|
81
|
+
const call = warn_stub.firstCall;
|
|
82
|
+
t.is(call.args[0], message);
|
|
83
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...additional_context });
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
test('context logger error method handles Error objects', t => {
|
|
87
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
88
|
+
const error_stub = sinon.stub(logger, 'error');
|
|
89
|
+
|
|
90
|
+
const base_context = { component: 'test' };
|
|
91
|
+
const context_logger = create_context_logger(base_context);
|
|
92
|
+
|
|
93
|
+
const message = 'Error occurred';
|
|
94
|
+
const error = new Error('Test error');
|
|
95
|
+
|
|
96
|
+
context_logger.error(message, error);
|
|
97
|
+
|
|
98
|
+
t.true(error_stub.calledOnce);
|
|
99
|
+
const call = error_stub.firstCall;
|
|
100
|
+
t.is(call.args[0], message);
|
|
101
|
+
t.deepEqual(call.args[1].context, base_context);
|
|
102
|
+
t.is(call.args[1].error_message, 'Test error');
|
|
103
|
+
t.truthy(call.args[1].stack);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
test('context logger error method handles context objects', t => {
|
|
107
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
108
|
+
const error_stub = sinon.stub(logger, 'error');
|
|
109
|
+
|
|
110
|
+
const base_context = { component: 'test' };
|
|
111
|
+
const context_logger = create_context_logger(base_context);
|
|
112
|
+
|
|
113
|
+
const message = 'Error occurred';
|
|
114
|
+
const error_context = { error_code: 500, details: 'Server error' };
|
|
115
|
+
|
|
116
|
+
context_logger.error(message, error_context);
|
|
117
|
+
|
|
118
|
+
t.true(error_stub.calledOnce);
|
|
119
|
+
const call = error_stub.firstCall;
|
|
120
|
+
t.is(call.args[0], message);
|
|
121
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...error_context });
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test('context logger debug method with context', t => {
|
|
125
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
126
|
+
const debug_stub = sinon.stub(logger, 'debug');
|
|
127
|
+
|
|
128
|
+
const base_context = { component: 'test' };
|
|
129
|
+
const context_logger = create_context_logger(base_context);
|
|
130
|
+
|
|
131
|
+
const message = 'Debug message';
|
|
132
|
+
const debug_context = { debug_info: 'test_data' };
|
|
133
|
+
|
|
134
|
+
context_logger.debug(message, debug_context);
|
|
135
|
+
|
|
136
|
+
t.true(debug_stub.calledOnce);
|
|
137
|
+
const call = debug_stub.firstCall;
|
|
138
|
+
t.is(call.args[0], message);
|
|
139
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...debug_context });
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('log_operation method includes operation and duration', t => {
|
|
143
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
144
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
145
|
+
|
|
146
|
+
const base_context = { component: 'test' };
|
|
147
|
+
const context_logger = create_context_logger(base_context);
|
|
148
|
+
|
|
149
|
+
const operation = 'database_write';
|
|
150
|
+
const duration = 150;
|
|
151
|
+
const additional_context = { records_affected: 5 };
|
|
152
|
+
|
|
153
|
+
context_logger.log_operation(operation, duration, additional_context);
|
|
154
|
+
|
|
155
|
+
t.true(info_stub.calledOnce);
|
|
156
|
+
const call = info_stub.firstCall;
|
|
157
|
+
t.is(call.args[0], `Operation completed: ${operation}`);
|
|
158
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...additional_context, operation });
|
|
159
|
+
t.is(call.args[1].duration_ms, duration);
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test('log_request method includes request_id and operation', t => {
|
|
163
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
164
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
165
|
+
|
|
166
|
+
const base_context = { component: 'test' };
|
|
167
|
+
const context_logger = create_context_logger(base_context);
|
|
168
|
+
|
|
169
|
+
const request_id = 'req_123';
|
|
170
|
+
const operation = 'find_one';
|
|
171
|
+
const additional_context = { collection: 'users' };
|
|
172
|
+
|
|
173
|
+
context_logger.log_request(request_id, operation, additional_context);
|
|
174
|
+
|
|
175
|
+
t.true(info_stub.calledOnce);
|
|
176
|
+
const call = info_stub.firstCall;
|
|
177
|
+
t.is(call.args[0], `Request: ${operation}`);
|
|
178
|
+
t.is(call.args[1].request_id, request_id);
|
|
179
|
+
t.deepEqual(call.args[1].context, { ...base_context, ...additional_context, operation });
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test('context logger methods work with empty base context', t => {
|
|
183
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
184
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
185
|
+
|
|
186
|
+
const context_logger = create_context_logger();
|
|
187
|
+
|
|
188
|
+
context_logger.info('Test message', { test: 'data' });
|
|
189
|
+
|
|
190
|
+
t.true(info_stub.calledOnce);
|
|
191
|
+
const call = info_stub.firstCall;
|
|
192
|
+
t.deepEqual(call.args[1].context, { test: 'data' });
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
test('context logger methods work with empty additional context', t => {
|
|
196
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
197
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
198
|
+
|
|
199
|
+
const base_context = { component: 'test' };
|
|
200
|
+
const context_logger = create_context_logger(base_context);
|
|
201
|
+
|
|
202
|
+
context_logger.info('Test message');
|
|
203
|
+
|
|
204
|
+
t.true(info_stub.calledOnce);
|
|
205
|
+
const call = info_stub.firstCall;
|
|
206
|
+
t.deepEqual(call.args[1].context, base_context);
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
test('context logger handles undefined context gracefully', t => {
|
|
210
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
211
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
212
|
+
|
|
213
|
+
const context_logger = create_context_logger();
|
|
214
|
+
|
|
215
|
+
context_logger.info('Test message');
|
|
216
|
+
|
|
217
|
+
t.true(info_stub.calledOnce);
|
|
218
|
+
const call = info_stub.firstCall;
|
|
219
|
+
t.deepEqual(call.args[1].context, {});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test('log_operation works with minimal parameters', t => {
|
|
223
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
224
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
225
|
+
|
|
226
|
+
const context_logger = create_context_logger();
|
|
227
|
+
|
|
228
|
+
context_logger.log_operation('test_op', 100);
|
|
229
|
+
|
|
230
|
+
t.true(info_stub.calledOnce);
|
|
231
|
+
const call = info_stub.firstCall;
|
|
232
|
+
t.is(call.args[0], 'Operation completed: test_op');
|
|
233
|
+
t.is(call.args[1].duration_ms, 100);
|
|
234
|
+
t.deepEqual(call.args[1].context, { operation: 'test_op' });
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test('log_request works with minimal parameters', t => {
|
|
238
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
239
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
240
|
+
|
|
241
|
+
const context_logger = create_context_logger();
|
|
242
|
+
|
|
243
|
+
context_logger.log_request('req_456', 'update_one');
|
|
244
|
+
|
|
245
|
+
t.true(info_stub.calledOnce);
|
|
246
|
+
const call = info_stub.firstCall;
|
|
247
|
+
t.is(call.args[0], 'Request: update_one');
|
|
248
|
+
t.is(call.args[1].request_id, 'req_456');
|
|
249
|
+
t.deepEqual(call.args[1].context, { operation: 'update_one' });
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
test('context merging preserves base context when additional context is empty', t => {
|
|
253
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
254
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
255
|
+
|
|
256
|
+
const base_context = { component: 'test', pid: 999 };
|
|
257
|
+
const context_logger = create_context_logger(base_context);
|
|
258
|
+
|
|
259
|
+
context_logger.info('Test message', {});
|
|
260
|
+
|
|
261
|
+
t.true(info_stub.calledOnce);
|
|
262
|
+
const call = info_stub.firstCall;
|
|
263
|
+
t.deepEqual(call.args[1].context, base_context);
|
|
264
|
+
});
|
|
265
|
+
|
|
266
|
+
test('additional context overrides base context for same keys', t => {
|
|
267
|
+
const { logger, create_context_logger } = create_logger('test');
|
|
268
|
+
const info_stub = sinon.stub(logger, 'info');
|
|
269
|
+
|
|
270
|
+
const base_context = { component: 'test', operation: 'base_op' };
|
|
271
|
+
const context_logger = create_context_logger(base_context);
|
|
272
|
+
|
|
273
|
+
context_logger.info('Test message', { operation: 'override_op', extra: 'data' });
|
|
274
|
+
|
|
275
|
+
t.true(info_stub.calledOnce);
|
|
276
|
+
const call = info_stub.firstCall;
|
|
277
|
+
t.deepEqual(call.args[1].context, {
|
|
278
|
+
component: 'test',
|
|
279
|
+
operation: 'override_op',
|
|
280
|
+
extra: 'data'
|
|
281
|
+
});
|
|
282
|
+
});
|