Skip to content

Robottest#119

Closed
thestumonkey wants to merge 3 commits intoSimpleOpenSoftware:mainfrom
thestumonkey:pytest
Closed

Robottest#119
thestumonkey wants to merge 3 commits intoSimpleOpenSoftware:mainfrom
thestumonkey:pytest

Conversation

@thestumonkey
Copy link
Contributor

@thestumonkey thestumonkey commented Sep 24, 2025

Added the tests folder in root, which test the endpoints and an integration test
I went for robot as I'm hoping that one can declare tests, and then get AI to make the functionality and pass the tests, ATDD style.
Not completly convinced with Robot, but I'm getting hte hang of it.
Run make test-robot

Summary by CodeRabbit

  • New Features

    • User update endpoint now accepts a dedicated update payload, enabling partial updates.
    • Added support for managing the “is_superuser” flag on user creation and update (admin-only).
  • Documentation

    • Added a comprehensive README for the API test suite with setup, execution, coverage, and troubleshooting guidance.
  • Tests

    • Introduced extensive Robot Framework suites covering Authentication, Chat, Conversation, Memory, Health, Client/Queue, and System Administration.
    • Added reusable testing keywords and environment/test data resources.
    • Provided a master suite to orchestrate all API tests.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 24, 2025

Walkthrough

Refactors user update flow to accept UserUpdate and delegate updating to the manager, adding is_superuser fields to user schemas. Updates router and controller accordingly. Adds comprehensive Robot Framework test suites, resources, and config modules to cover authentication, chat, conversations, memory, health, client/queue, and system-admin endpoints.

Changes

Cohort / File(s) Summary of changes
User update API refactor
backends/advanced/src/advanced_omi_backend/controllers/user_controller.py, backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py
Switch update handlers from UserCreate to UserUpdate; controller now delegates updates directly to user_manager.update; minor debug print added; imports updated.
User models/schema
backends/advanced/src/advanced_omi_backend/users.py
Added is_superuser to UserCreate (default False) and UserUpdate (Optional); added UserUpdate.create_update_dict_superuser to include superuser field in updates.
Test suites
tests/auth_tests.robot, tests/chat_tests.robot, tests/conversation_tests.robot, tests/memory_tests.robot, tests/health_tests.robot, tests/client_queue_tests.robot, tests/system_admin_tests.robot, tests/all_api_tests.robot
New Robot Framework suites covering auth, chat, conversations, memory, health, client/queue, system admin, plus a master orchestrator suite.
Test resources/keywords
tests/resources/auth_keywords.robot, tests/resources/chat_keywords.robot, tests/resources/conversation_keywords.robot, tests/resources/memory_keywords.robot, tests/resources/login_resources.robot, tests/resources/setup_resources.robot
New reusable keywords for sessions, auth, CRUD flows, chat interactions, conversation management, memory operations, and setup/health checks.
Test documentation
tests/README.md
Added README documenting test structure, setup, execution, coverage, and maintenance.
Test configuration/data
tests/test_env.py, tests/test_data.py
New environment/config variables and static test data/constants for endpoints, users, and samples.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant R as User Router (/api/users/{id})
  participant UC as User Controller
  participant UM as User Manager
  participant DB as Database

  Note over C,R: Update User (PUT/PATCH)
  C->>R: user_id, UserUpdate payload
  R->>UC: update_user(user_id, user_data: UserUpdate)
  UC->>UM: get(user_id)
  UM->>DB: fetch user by id
  DB-->>UM: user or not found
  UM-->>UC: user or raise
  UC->>UM: update(user, user_data)  <!-- changed: delegate with UserUpdate -->
  UM->>DB: apply update (incl. optional is_superuser)
  DB-->>UM: updated user
  UM-->>UC: updated user
  UC-->>R: updated user
  R-->>C: 200 OK + body
  Note over UC,UM: Path updated to accept UserUpdate and manager-driven update
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Better init system #74 — Also modifies advanced_omi_backend user schema (adds primary_speakers to User/UserRead), overlapping domain with this PR’s user model changes.

Poem

I nibbled the schemas, a byte at a time,
Flipped Create to Update—oh what a climb!
Tests sprouted like clover across the land,
Bots and bunnies hopping hand in hand.
Superuser whispers in carrot-code rhyme,
“All green checks soon—now watch me shine!” 🥕✨

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Title Check ⚠️ Warning The current title “Robottest” is too vague and does not clearly convey the main scope or purpose of the changes, which include adding a comprehensive Robot Framework test suite and updating the user update API to use the new UserUpdate model. Consider renaming the pull request to something more descriptive like “Add Robot Framework API integration tests and update UserUpdate endpoint”, which clearly highlights the addition of tests and the related backend changes.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@AnkushMalaker
Copy link
Collaborator

@coderabbitai review

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 29, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 14

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8ffd97a and 3ba5506.

📒 Files selected for processing (20)
  • backends/advanced/src/advanced_omi_backend/controllers/user_controller.py (3 hunks)
  • backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py (2 hunks)
  • backends/advanced/src/advanced_omi_backend/users.py (2 hunks)
  • tests/README.md (1 hunks)
  • tests/all_api_tests.robot (1 hunks)
  • tests/auth_tests.robot (1 hunks)
  • tests/chat_tests.robot (1 hunks)
  • tests/client_queue_tests.robot (1 hunks)
  • tests/conversation_tests.robot (1 hunks)
  • tests/health_tests.robot (1 hunks)
  • tests/memory_tests.robot (1 hunks)
  • tests/resources/auth_keywords.robot (1 hunks)
  • tests/resources/chat_keywords.robot (1 hunks)
  • tests/resources/conversation_keywords.robot (1 hunks)
  • tests/resources/login_resources.robot (1 hunks)
  • tests/resources/memory_keywords.robot (1 hunks)
  • tests/resources/setup_resources.robot (1 hunks)
  • tests/system_admin_tests.robot (1 hunks)
  • tests/test_data.py (1 hunks)
  • tests/test_env.py (1 hunks)
🧰 Additional context used
🪛 Ruff (0.13.1)
tests/test_env.py

28-28: Possible hardcoded password assigned to: "TEST_USER_PASSWORD"

(S105)

backends/advanced/src/advanced_omi_backend/routers/modules/user_routes.py

33-33: Unused function argument: current_user

(ARG001)


33-33: Do not perform function call Depends in argument defaults; instead, perform the call within the function, or read the default from a module-level singleton variable

(B008)

Comment on lines +36 to +51
def create_update_dict_superuser(self):
"""Create update dictionary for superuser operations."""
update_dict = {}
if self.email is not None:
update_dict["email"] = self.email
if self.password is not None:
update_dict["password"] = self.password
if self.is_active is not None:
update_dict["is_active"] = self.is_active
if self.is_verified is not None:
update_dict["is_verified"] = self.is_verified
if self.is_superuser is not None:
update_dict["is_superuser"] = self.is_superuser
if self.display_name is not None:
update_dict["display_name"] = self.display_name
return update_dict
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Override create_update_dict so updates actually persist.

UserManager.update calls user_update.create_update_dict(). Because this class doesn’t override that method, the manager still uses the default implementation, which omits display_name and any other custom fields. In practice, requests attempting to change display_name (or even is_superuser, which you’re trying to fix) will silently no-op. Please override create_update_dict() (or replace the manager call with your new helper) instead of introducing an unused create_update_dict_superuser. Right now the update endpoint can’t apply the fields this PR intends to support.

🤖 Prompt for AI Agents
In backends/advanced/src/advanced_omi_backend/users.py around lines 36 to 51,
you added create_update_dict_superuser but did not override create_update_dict,
so UserManager.update still uses the base method and ignores display_name and
other custom fields; replace or rename this helper by overriding
create_update_dict to build and return the update_dict (including email,
password, is_active, is_verified, is_superuser, display_name) so the manager
picks up and persists those fields, and ensure any call sites use the overridden
method rather than the old helper.

Comment on lines +8 to +42
Run Auth Tests
[Documentation] Execute authentication and user management tests
[Tags] auth users suite
Run Tests auth_tests.robot

Run Memory Tests
[Documentation] Execute memory management tests
[Tags] memory suite
Run Tests memory_tests.robot

Run Conversation Tests
[Documentation] Execute conversation management tests
[Tags] conversation suite
Run Tests conversation_tests.robot

Run Health Tests
[Documentation] Execute health and status tests
[Tags] health status suite
Run Tests health_tests.robot

Run Chat Tests
[Documentation] Execute chat service tests
[Tags] chat suite
Run Tests chat_tests.robot

Run Client Queue Tests
[Documentation] Execute client and queue management tests
[Tags] client queue suite
Run Tests client_queue_tests.robot

Run System Admin Tests
[Documentation] Execute system and admin tests
[Tags] system admin suite
Run Tests system_admin_tests.robot

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Master suite never triggers the underlying suites

Every test case in this file just calls Run Tests, but that keyword only logs a message and returns. When you execute all_api_tests.robot, none of the underlying suite files actually run, so failures in auth_tests.robot, memory_tests.robot, etc. go completely unnoticed. This defeats the whole point of the orchestrator. Please make Run Tests invoke the suite (for example via Run Process robot ${test_file} and assert the return code) or restructure the suite so that the real test files are imported/executed directly. Without that fix the master suite will always pass even if the API tests break.

Apply this diff (add the Process library and execute each suite):

*** Settings ***
 Documentation    Master Test Suite for All Friend-Lite API Endpoints
 Suite Setup      Master Suite Setup
 Suite Teardown   Master Suite Teardown
+Library          Process

*** Keywords ***
 Run Tests
     [Documentation]    Run a specific test file
     [Arguments]    ${test_file}
-    Log    Executing: ${test_file}
-    # Note: This is a placeholder - actual test execution handled by robot command
+    ${result}=    Run Process    robot    ${test_file}    stdout=STDOUT    stderr=STDOUT
+    Should Be Equal As Integers    ${result.rc}    0    Execution of ${test_file} failed

Also applies to: 45-58

🤖 Prompt for AI Agents
In tests/all_api_tests.robot around lines 8-42 (and also 45-58), the suite only
calls the custom Run Tests keyword which merely logs and does not execute the
underlying suites; import the Robot Process library at the top and replace each
Run Tests call with a Run Process invocation of the robot runner for that file,
capturing the returned result object and asserting the process return code is
zero (e.g. ${result}=  Run Process  robot  <suite_file>; Should Be Equal As
Integers  ${result.rc}  0) so each underlying suite actually runs and failures
fail the master suite.

Comment on lines +100 to +107
Should Be Equal As Integers ${response.status_code} 200
Should Be True isinstance($response.json(), list)

# Should contain at least the admin user
${users}= Set Variable ${response.json()}
${admin_found}= Set Variable ${False}
FOR ${user} IN @{users}
IF '${user}[email]' == '${ADMIN_EMAIL}'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix JSON parsing – current syntax will crash the suite.

Line 101 evaluates isinstance($response.json(), list) and Line 104 tries to assign ${response.json()}. Robot Framework doesn’t call methods via ${...} or $... in these contexts, so you’ll hit “Variable '${response.json()}' not found” or a syntax error before any assertions run. Grab the body with Evaluate $response.json() (or a helper keyword) and then assert on the resulting object. The other occurrences of ${response.json()} / $response.json() in this suite need the same treatment.

-    Should Be True     isinstance($response.json(), list)
-
-    ${users}=    Set Variable    ${response.json()}
+    ${users}=    Evaluate    $response.json()
+    ${is_list}=  Evaluate    isinstance($users, list)
+    Should Be True    ${is_list}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Should Be Equal As Integers ${response.status_code} 200
Should Be True isinstance($response.json(), list)
# Should contain at least the admin user
${users}= Set Variable ${response.json()}
${admin_found}= Set Variable ${False}
FOR ${user} IN @{users}
IF '${user}[email]' == '${ADMIN_EMAIL}'
Should Be Equal As Integers ${response.status_code} 200
${users}= Evaluate $response.json()
${is_list}= Evaluate isinstance($users, list)
Should Be True ${is_list}
# Should contain at least the admin user
${admin_found}= Set Variable ${False}
FOR ${user} IN @{users}
IF '${user}[email]' == '${ADMIN_EMAIL}'
🤖 Prompt for AI Agents
In tests/auth_tests.robot around lines 100 to 107, the code calls
response.json() inside Robot variable syntax which will raise a "Variable ...
not found" or syntax error; instead evaluate and store the JSON once and reuse
it: use Evaluate    $response.json() (or a helper keyword) to assign the body to
a Robot variable (e.g., ${users}) then assert its type and status using that
variable and update all other occurrences of ${response.json()} /
$response.json() in the suite to use the evaluated ${users} (or similarly named)
variable.

Comment on lines +42 to +55
${response}= GET On Session api /api/queue/jobs headers=${headers} params=${params}
Should Be Equal As Integers ${response.status_code} 200

${result}= Set Variable ${response.json()}
Dictionary Should Contain Key ${result} jobs
Dictionary Should Contain Key ${result} pagination

${jobs}= Set Variable ${result}[jobs]
Should Be True isinstance($jobs, list)

${pagination}= Set Variable ${result}[pagination]
Dictionary Should Contain Key ${pagination} total
Dictionary Should Contain Key ${pagination} limit
Dictionary Should Contain Key ${pagination} offset
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Use Evaluate (or a helper) to read response.json().

Line 45 assigns ${response.json()} directly, then downstream logic assumes it succeeded. Robot can’t resolve that method call in variable syntax, so this test (and others below with the same pattern) will abort with a missing-variable error. Fetch the JSON payload via Evaluate $response.json() (or a dedicated keyword) before asserting on it. Apply the same fix to the other ${response.json()} usages in this file.

-    ${result}=     Set Variable    ${response.json()}
+    ${result}=     Evaluate    $response.json()
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
${response}= GET On Session api /api/queue/jobs headers=${headers} params=${params}
Should Be Equal As Integers ${response.status_code} 200
${result}= Set Variable ${response.json()}
Dictionary Should Contain Key ${result} jobs
Dictionary Should Contain Key ${result} pagination
${jobs}= Set Variable ${result}[jobs]
Should Be True isinstance($jobs, list)
${pagination}= Set Variable ${result}[pagination]
Dictionary Should Contain Key ${pagination} total
Dictionary Should Contain Key ${pagination} limit
Dictionary Should Contain Key ${pagination} offset
${response}= GET On Session api /api/queue/jobs headers=${headers} params=${params}
Should Be Equal As Integers ${response.status_code} 200
${result}= Evaluate $response.json()
Dictionary Should Contain Key ${result} jobs
Dictionary Should Contain Key ${result} pagination
${jobs}= Set Variable ${result}[jobs]
Should Be True isinstance($jobs, list)
${pagination}= Set Variable ${result}[pagination]
Dictionary Should Contain Key ${pagination} total
Dictionary Should Contain Key ${pagination} limit
Dictionary Should Contain Key ${pagination} offset
🤖 Prompt for AI Agents
In tests/client_queue_tests.robot around lines 42 to 55, the test assigns
${response.json()} directly which Robot Framework cannot evaluate in variable
syntax; update the code to call the JSON parser via Evaluate (e.g. use Evaluate 
response.json() with the response variable in scope or create a helper keyword
that returns response.json()) and assign that result to ${result}, then proceed
with the existing assertions; apply the same change to every other occurrence in
this file where ${response.json()} is used directly.

Dictionary Should Contain Key ${health} critical_services_healthy

# Verify status is one of expected values
Should Be True '${health}[status]' in ['healthy', 'degraded', 'critical']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Remove the quotes around the expression.

Should Be True '${health}[status]' in […] wraps the entire expression in quotes, so Python evaluates it as a literal string, making the assertion fail every time. Use ${health}[status] in ['healthy', 'degraded', 'critical'] instead. (robotframework.org)

🤖 Prompt for AI Agents
In tests/health_tests.robot around line 29, the assertion wraps the whole
expression in single quotes causing Robot Framework to treat it as a literal
string; remove the surrounding quotes so the argument is evaluated as an
expression: change Should Be True    '${health}[status]' in ['healthy',
'degraded', 'critical'] to use ${health}[status] in ['healthy', 'degraded',
'critical'] so the membership check runs correctly.

Comment on lines +76 to +80
Verify Unauthorized Access
[Documentation] Verify endpoint requires authentication
[Arguments] ${method} ${endpoint} &{kwargs}
${response}= Run Keyword And Expect Error * Run Keyword ${method} On Session api ${endpoint} expected_status=401 &{kwargs}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix Verify Unauthorized Access: wrong expectation handling.

Run Keyword And Expect Error only passes when the wrapped keyword raises, but GET/POST On Session … expected_status=401 succeeds and returns a normal response. This keyword will therefore fail every time it’s used. Call the request keyword directly (or capture the response) and assert on the status without wrapping it in Run Keyword And Expect Error. (robot-framework.readthedocs.io)

🤖 Prompt for AI Agents
tests/resources/auth_keywords.robot lines 76-80: the custom keyword Verify
Unauthorized Access incorrectly wraps the session request in Run Keyword And
Expect Error which expects an exception but the HTTP request returns a normal
response; remove Run Keyword And Expect Error, call the `${method} On Session`
keyword directly (or store its return value in `${response}`), and assert the
response status is 401 (e.g. use Should Be Equal As Integers or a Robot
assertion on `${response.status}`) so the test verifies the unauthorized status
instead of expecting an exception.

Comment on lines +132 to +138
# Upload test audio file to create a conversation
${test_audio_file}= Set Variable /Users/stu/repos/friend-lite/pytest/extras/test-audios/DIY Experts Glass Blowing_16khz_mono_4min.wav

# Use curl to upload the file (Robot Framework doesn't handle file uploads well)
${curl_cmd}= Set Variable curl -s -X POST -H "Authorization: Bearer ${token}" -F "files=@${test_audio_file}" -F "device_name=${device_name}" http://localhost:8001/api/process-audio-files
${result}= Run Process ${curl_cmd} shell=True

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Parameterize the test audio path
The test audio file is hard-coded to /Users/stu/..., so these keywords will fail anywhere other than your workstation and break CI runs. Please switch to a relative path (e.g., build it from ${CURDIR}/${EXECDIR} or expose it via test_env.py) so the suite stays portable. (robotframework.org)

🤖 Prompt for AI Agents
tests/resources/conversation_keywords.robot lines 132-138: the test audio path
is hard-coded to a user-specific absolute path which breaks on other machines
and CI; change it to build a relative path using Robot variables (e.g. ${CURDIR}
and/or ${EXECDIR}) or read the path from a test_env variable (exposed by
test_env.py), assign that computed path to ${test_audio_file}, and use that
variable in the curl command so the file lookup is portable across environments.

Comment on lines +14 to +18
Log To Console Credentials: ${credentials}

# Encode the credentials using base64 encoding
${encoded}= Evaluate str(base64.b64encode('${credentials}'.encode('utf-8')), 'utf-8') modules=base64
Log To Console Encoded Credentials: ${encoded}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Remove the plaintext credential logging.

Line 14 and Line 18 write both the raw username:password string and its Base64 encoding straight to the console. That leaks reusable secrets into logs and violates our security posture. Please drop these logging statements (or mask them entirely) so we don’t persist credentials anywhere.

-    Log To Console    Credentials: ${credentials}
@@
-    Log To Console    Encoded Credentials: ${encoded}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
Log To Console Credentials: ${credentials}
# Encode the credentials using base64 encoding
${encoded}= Evaluate str(base64.b64encode('${credentials}'.encode('utf-8')), 'utf-8') modules=base64
Log To Console Encoded Credentials: ${encoded}
# Encode the credentials using base64 encoding
${encoded}= Evaluate str(base64.b64encode('${credentials}'.encode('utf-8')), 'utf-8') modules=base64
🤖 Prompt for AI Agents
In tests/resources/login_resources.robot around lines 14 to 18, the test
currently logs the raw credentials and their Base64 encoding which leaks
secrets; remove both Log To Console statements (the one logging ${credentials}
and the one logging ${encoded}) or replace them with non-sensitive messages
(e.g., log that credentials were set or log a masked value like ****) so that
neither the plaintext nor the encoded credential is ever written to logs.

Comment on lines +42 to +45
IF ${headers} == '{}'
&{headers}= Create Basic Auth Header ${ADMIN_EMAIL} ${ADMIN_PASSWORD}
END
Create Session api ${base_url} verify=True headers=${headers}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Restore default auth header initialization

Setup API Session tries to detect missing headers with IF ${headers} == '{}', but scalar comparison against the string literal '{}' is never true for an actual dictionary. As a result the basic-auth fallback is dead code and we create sessions without any Authorization header, breaking every keyword that assumes the admin basic creds are preloaded. (stackoverflow.com)

Patch the emptiness check to use Robot’s dictionary-aware comparison (or len(${headers}) == 0) before building the session:

-    IF    ${headers} == '{}'
-        &{headers}=    Create Basic Auth Header     ${ADMIN_EMAIL}    ${ADMIN_PASSWORD}
-    END
-    Create Session    api    ${base_url}    verify=True headers=${headers}
+    IF    ${headers} == &{EMPTY}
+        &{headers}=    Create Basic Auth Header    ${ADMIN_EMAIL}    ${ADMIN_PASSWORD}
+    END
+    Create Session    api    ${base_url}    headers=${headers}    verify=True
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
IF ${headers} == '{}'
&{headers}= Create Basic Auth Header ${ADMIN_EMAIL} ${ADMIN_PASSWORD}
END
Create Session api ${base_url} verify=True headers=${headers}
IF ${headers} == &{EMPTY}
&{headers}= Create Basic Auth Header ${ADMIN_EMAIL} ${ADMIN_PASSWORD}
END
Create Session api ${base_url} headers=${headers} verify=True
🤖 Prompt for AI Agents
In tests/resources/setup_resources.robot around lines 42 to 45, the IF checks
`${headers} == '{}'` which compares a scalar string literal and never matches an
actual empty dictionary, so the Basic Auth fallback never runs; change the
condition to a dictionary-aware emptiness check such as `IF    len(${headers})
== 0` or use Robot Framework's dictionary comparison to detect an empty mapping,
then call Create Basic Auth Header when true so the session is created with the
admin Authorization header.

Comment on lines +22 to +24
${config}= Set Variable ${response.json()}
# Auth config structure may vary, just verify it's valid JSON
Should Be True isinstance($config, dict)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Adjust JSON handling to avoid ${response.json()} failures.

At Line 22 you assign ${response.json()} straight into ${config}. Robot treats that as a literal variable lookup and raises “Variable '${response.json()}' not found”, so the suite never reaches the assertions. Please switch to Evaluate $response.json() (or a helper keyword) and update the rest of this file wherever the same pattern appears.

-    ${config}=      Set Variable    ${response.json()}
+    ${config}=      Evaluate    $response.json()

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In tests/system_admin_tests.robot around lines 22 to 24, the assignment uses Set
Variable    ${response.json()} which Robot treats as a literal variable lookup
and fails; replace that assignment to evaluate the method call (e.g., use
Evaluate to call response.json() and assign its return to ${config}) and update
any other occurrences in this file doing the same pattern so all JSON responses
are obtained via Evaluate (or a helper keyword) rather than using
${response.json()} as a variable name.

@thestumonkey thestumonkey closed this by deleting the head repository Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants