mirror of
				https://github.com/kevinveenbirkenbach/computer-playbook.git
				synced 2025-11-04 04:08:15 +00:00 
			
		
		
		
	Optimized Docker Matrix Role in Preparation for use on CyMaIS.Cloud Server
This commit is contained in:
		@@ -0,0 +1,2 @@
 | 
			
		||||
from pkgutil import extend_path
 | 
			
		||||
__path__ = extend_path(__path__, __name__)
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
CYMAIS_ENVIRONMENT:       "production"
 | 
			
		||||
 | 
			
		||||
HOST_CURRENCY:            "EUR"
 | 
			
		||||
HOST_TIMEZONE:            "UTC"
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ SSH_PORT={{ports.public.ssh[application_id]}}
 | 
			
		||||
SSH_LISTEN_PORT=22
 | 
			
		||||
DOMAIN={{domains[application_id]}}
 | 
			
		||||
SSH_DOMAIN={{domains[application_id]}}
 | 
			
		||||
RUN_MODE="{{run_mode}}"
 | 
			
		||||
RUN_MODE="{{ 'dev' if (CYMAIS_ENVIRONMENT | lower) == 'development' else 'prod' }}"
 | 
			
		||||
ROOT_URL="{{ web_protocol }}://{{domains[application_id]}}/"
 | 
			
		||||
 | 
			
		||||
# Mail Configuration 
 | 
			
		||||
 
 | 
			
		||||
@@ -15,3 +15,5 @@ csp:
 | 
			
		||||
  flags:
 | 
			
		||||
    script-src:
 | 
			
		||||
      unsafe-inline: true
 | 
			
		||||
    style-src:
 | 
			
		||||
      unsafe-inline: true
 | 
			
		||||
							
								
								
									
										5
									
								
								roles/docker-matrix/Todo.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								roles/docker-matrix/Todo.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
# Todo 
 | 
			
		||||
- Enable Whatsapp by default
 | 
			
		||||
- Enable Telegram by default
 | 
			
		||||
- Enable Slack by default
 | 
			
		||||
- Enable ChatGPT by default
 | 
			
		||||
							
								
								
									
										2
									
								
								roles/docker-matrix/filter_plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								roles/docker-matrix/filter_plugins/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,2 @@
 | 
			
		||||
from pkgutil import extend_path
 | 
			
		||||
__path__ = extend_path(__path__, __name__)
 | 
			
		||||
							
								
								
									
										13
									
								
								roles/docker-matrix/filter_plugins/bridge_filters.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								roles/docker-matrix/filter_plugins/bridge_filters.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
			
		||||
def filter_enabled_bridges(bridges, plugins):
 | 
			
		||||
    """
 | 
			
		||||
    Return only those bridge definitions whose 'bridge_name' is set to True in plugins.
 | 
			
		||||
    :param bridges: list of dicts, each with a 'bridge_name' key
 | 
			
		||||
    :param plugins: dict mapping bridge_name to a boolean
 | 
			
		||||
    """
 | 
			
		||||
    return [b for b in bridges if plugins.get(b['bridge_name'], False)]
 | 
			
		||||
 | 
			
		||||
class FilterModule(object):
 | 
			
		||||
    def filters(self):
 | 
			
		||||
        return {
 | 
			
		||||
            'filter_enabled_bridges': filter_enabled_bridges,
 | 
			
		||||
        }
 | 
			
		||||
@@ -1,4 +1,13 @@
 | 
			
		||||
---
 | 
			
		||||
- name: Load bridges configuration
 | 
			
		||||
  include_vars:
 | 
			
		||||
    file: "bridges.yml"
 | 
			
		||||
 | 
			
		||||
- name: Filter enabled bridges and register as fact
 | 
			
		||||
  set_fact:
 | 
			
		||||
    bridges: "{{ bridges_configuration | filter_enabled_bridges(applications[application_id].plugins) }}"
 | 
			
		||||
  changed_when: false
 | 
			
		||||
 | 
			
		||||
- name: "include docker-central-database"
 | 
			
		||||
  include_role: 
 | 
			
		||||
    name: docker-central-database
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,11 @@ services:
 | 
			
		||||
      interval: 1m
 | 
			
		||||
      timeout: 10s
 | 
			
		||||
      retries: 3
 | 
			
		||||
{% if bridges | bool %}
 | 
			
		||||
{% include 'templates/docker/container/depends-on-also-database.yml.j2' %}
 | 
			
		||||
{% else %}
 | 
			
		||||
{% include 'templates/docker/container/depends-on-just-database.yml.j2' %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
{% for item in bridges %}
 | 
			
		||||
      mautrix-{{item.bridge_name}}:
 | 
			
		||||
        condition: service_healthy
 | 
			
		||||
@@ -61,47 +65,47 @@ services:
 | 
			
		||||
      retries: 3
 | 
			
		||||
{% include 'templates/docker/container/networks.yml.j2' %}
 | 
			
		||||
{% endfor %}
 | 
			
		||||
# Deactivated chatgpt. 
 | 
			
		||||
# @todo needs to be reactivated as soon as bug is found
 | 
			
		||||
#  matrix-chatgpt-bot:
 | 
			
		||||
#    restart: {{docker_restart_policy}}
 | 
			
		||||
#    container_name: matrix-chatgpt
 | 
			
		||||
#    image: ghcr.io/matrixgpt/matrix-chatgpt-bot:latest
 | 
			
		||||
#    volumes:
 | 
			
		||||
#      - chatgpt_data:/storage
 | 
			
		||||
#    environment:
 | 
			
		||||
#      OPENAI_API_KEY: '{{applications[application_id].credentials.chatgpt_bridge_openai_api_key}}'
 | 
			
		||||
#      # Uncomment the next two lines if you are using Azure OpenAI API
 | 
			
		||||
#      # OPENAI_AZURE: 'false'
 | 
			
		||||
#      # CHATGPT_REVERSE_PROXY: 'your-completion-endpoint-here'
 | 
			
		||||
#      CHATGPT_CONTEXT: 'thread'
 | 
			
		||||
#      CHATGPT_API_MODEL: 'gpt-3.5-turbo'
 | 
			
		||||
#      # Uncomment and edit the next line if needed
 | 
			
		||||
#      # CHATGPT_PROMPT_PREFIX: 'Instructions:\nYou are ChatGPT, a large language model trained by OpenAI.'
 | 
			
		||||
#      # CHATGPT_IGNORE_MEDIA: 'false'
 | 
			
		||||
#      CHATGPT_REVERSE_PROXY: 'https://api.openai.com/v1/chat/completions'
 | 
			
		||||
#      # Uncomment and edit the next line if needed
 | 
			
		||||
#      # CHATGPT_TEMPERATURE: '0.8'
 | 
			
		||||
#      # Uncomment and edit the next line if needed
 | 
			
		||||
#      #CHATGPT_MAX_CONTEXT_TOKENS: '4097'
 | 
			
		||||
#      CHATGPT_MAX_PROMPT_TOKENS: '3000'
 | 
			
		||||
#      KEYV_BACKEND: 'file'
 | 
			
		||||
#      KEYV_URL: ''
 | 
			
		||||
#      KEYV_BOT_ENCRYPTION: 'false'
 | 
			
		||||
#      KEYV_BOT_STORAGE: 'true'
 | 
			
		||||
#      MATRIX_HOMESERVER_URL: 'https://{{domains.synapse}}'
 | 
			
		||||
#      MATRIX_BOT_USERNAME: '@chatgptbot:{{applications.matrix.server_name}}'
 | 
			
		||||
#      MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}'
 | 
			
		||||
#      MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}'
 | 
			
		||||
#      MATRIX_DEFAULT_PREFIX: '!chatgpt'
 | 
			
		||||
#      MATRIX_DEFAULT_PREFIX_REPLY: 'false'
 | 
			
		||||
#      #MATRIX_BLACKLIST: ''
 | 
			
		||||
#      MATRIX_WHITELIST: ':{{applications.matrix.server_name}}'
 | 
			
		||||
#      MATRIX_AUTOJOIN: 'true'
 | 
			
		||||
#      MATRIX_ENCRYPTION: 'true'
 | 
			
		||||
#      MATRIX_THREADS: 'true'
 | 
			
		||||
#      MATRIX_PREFIX_DM: 'false'
 | 
			
		||||
#      MATRIX_RICH_TEXT: 'true'
 | 
			
		||||
{% if applications[application_id] | bool %}
 | 
			
		||||
  matrix-chatgpt-bot:
 | 
			
		||||
    restart: {{docker_restart_policy}}
 | 
			
		||||
    container_name: matrix-chatgpt
 | 
			
		||||
    image: ghcr.io/matrixgpt/matrix-chatgpt-bot:latest
 | 
			
		||||
    volumes:
 | 
			
		||||
      - chatgpt_data:/storage
 | 
			
		||||
    environment:
 | 
			
		||||
      OPENAI_API_KEY: '{{applications[application_id].credentials.chatgpt_bridge_openai_api_key}}'
 | 
			
		||||
      # Uncomment the next two lines if you are using Azure OpenAI API
 | 
			
		||||
      # OPENAI_AZURE: 'false'
 | 
			
		||||
      # CHATGPT_REVERSE_PROXY: 'your-completion-endpoint-here'
 | 
			
		||||
      CHATGPT_CONTEXT: 'thread'
 | 
			
		||||
      CHATGPT_API_MODEL: 'gpt-3.5-turbo'
 | 
			
		||||
      # Uncomment and edit the next line if needed
 | 
			
		||||
      # CHATGPT_PROMPT_PREFIX: 'Instructions:\nYou are ChatGPT, a large language model trained by OpenAI.'
 | 
			
		||||
      # CHATGPT_IGNORE_MEDIA: 'false'
 | 
			
		||||
      CHATGPT_REVERSE_PROXY: 'https://api.openai.com/v1/chat/completions'
 | 
			
		||||
      # Uncomment and edit the next line if needed
 | 
			
		||||
      # CHATGPT_TEMPERATURE: '0.8'
 | 
			
		||||
      # Uncomment and edit the next line if needed
 | 
			
		||||
      #CHATGPT_MAX_CONTEXT_TOKENS: '4097'
 | 
			
		||||
      CHATGPT_MAX_PROMPT_TOKENS: '3000'
 | 
			
		||||
      KEYV_BACKEND: 'file'
 | 
			
		||||
      KEYV_URL: ''
 | 
			
		||||
      KEYV_BOT_ENCRYPTION: 'false'
 | 
			
		||||
      KEYV_BOT_STORAGE: 'true'
 | 
			
		||||
      MATRIX_HOMESERVER_URL: 'https://{{domains.synapse}}'
 | 
			
		||||
      MATRIX_BOT_USERNAME: '@chatgptbot:{{applications.matrix.server_name}}'
 | 
			
		||||
      MATRIX_ACCESS_TOKEN: '{{ applications[application_id].credentials.chatgpt_bridge_access_token | default('') }}'
 | 
			
		||||
      MATRIX_BOT_PASSWORD: '{{applications[application_id].credentials.chatgpt_bridge_user_password}}'
 | 
			
		||||
      MATRIX_DEFAULT_PREFIX: '!chatgpt'
 | 
			
		||||
      MATRIX_DEFAULT_PREFIX_REPLY: 'false'
 | 
			
		||||
      #MATRIX_BLACKLIST: ''
 | 
			
		||||
      MATRIX_WHITELIST: ':{{applications.matrix.server_name}}'
 | 
			
		||||
      MATRIX_AUTOJOIN: 'true'
 | 
			
		||||
      MATRIX_ENCRYPTION: 'true'
 | 
			
		||||
      MATRIX_THREADS: 'true'
 | 
			
		||||
      MATRIX_PREFIX_DM: 'false'
 | 
			
		||||
      MATRIX_RICH_TEXT: 'true'
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
{% include 'templates/docker/compose/volumes.yml.j2' %}
 | 
			
		||||
  synapse_data:
 | 
			
		||||
 
 | 
			
		||||
@@ -61,7 +61,9 @@ oidc_providers:
 | 
			
		||||
    backchannel_logout_enabled: true
 | 
			
		||||
{% endif %}
 | 
			
		||||
 | 
			
		||||
{% if bridges | bool %}
 | 
			
		||||
app_service_config_files:
 | 
			
		||||
{% for item in bridges %}
 | 
			
		||||
  - {{registration_file_folder}}{{item.bridge_name}}.registration.yaml
 | 
			
		||||
{% endfor %}
 | 
			
		||||
{% endif %}
 | 
			
		||||
							
								
								
									
										30
									
								
								roles/docker-matrix/vars/bridges.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								roles/docker-matrix/vars/bridges.yml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
bridges_configuration:
 | 
			
		||||
  - database_password: "{{ applications[application_id].credentials.mautrix_whatsapp_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_whatsapp_bridge"
 | 
			
		||||
    database_name:      "mautrix_whatsapp_bridge"
 | 
			
		||||
    bridge_name:        "whatsapp"   
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_telegram_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_telegram_bridge"
 | 
			
		||||
    database_name:      "mautrix_telegram_bridge"
 | 
			
		||||
    bridge_name:        "telegram"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_signal_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_signal_bridge"
 | 
			
		||||
    database_name:      "mautrix_signal_bridge"
 | 
			
		||||
    bridge_name:        "signal"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_slack_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_slack_bridge"
 | 
			
		||||
    database_name:      "mautrix_slack_bridge"
 | 
			
		||||
    bridge_name:        "slack"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_facebook_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_facebook_bridge"
 | 
			
		||||
    database_name:      "mautrix_facebook_bridge"
 | 
			
		||||
    bridge_name:        "facebook"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_instagram_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_instagram_bridge"
 | 
			
		||||
    database_name:      "mautrix_instagram_bridge"
 | 
			
		||||
    bridge_name:        "instagram"
 | 
			
		||||
@@ -3,7 +3,6 @@ users:
 | 
			
		||||
  administrator:
 | 
			
		||||
    username:         "{{users.administrator.username}}" # Accountname of the matrix admin
 | 
			
		||||
playbook_tags:        "setup-all,start"                  # For the initial update use: install-all,ensure-matrix-users-created,start
 | 
			
		||||
role:                 "compose"                          # Role to setup Matrix. Valid values: ansible, compose
 | 
			
		||||
server_name:          "{{primary_domain}}"               # Adress for the account names etc.
 | 
			
		||||
synapse:
 | 
			
		||||
  version:            "latest"
 | 
			
		||||
@@ -30,3 +29,14 @@ csp:
 | 
			
		||||
    script-src:
 | 
			
		||||
      - "{{ domains.synapse }}"
 | 
			
		||||
      - "https://cdn.jsdelivr.net"
 | 
			
		||||
plugins:
 | 
			
		||||
# You need to enable them in the inventory file
 | 
			
		||||
  chatgpt:    false
 | 
			
		||||
  facebook:   false
 | 
			
		||||
  immesage:   false
 | 
			
		||||
  instagram:  false
 | 
			
		||||
  signal:     false
 | 
			
		||||
  slack:      false
 | 
			
		||||
  telegram:   false
 | 
			
		||||
  whatsapp:   false
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,38 +1,5 @@
 | 
			
		||||
---
 | 
			
		||||
application_id:            "matrix"
 | 
			
		||||
application_id:           "matrix"
 | 
			
		||||
database_type:            "postgres"
 | 
			
		||||
registration_file_folder: "/data/"
 | 
			
		||||
well_known_directory:     "{{nginx.directories.data.well_known}}/matrix/"
 | 
			
		||||
 | 
			
		||||
bridges:
 | 
			
		||||
  - database_password: "{{ applications[application_id].credentials.mautrix_whatsapp_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_whatsapp_bridge"
 | 
			
		||||
    database_name:      "mautrix_whatsapp_bridge"
 | 
			
		||||
    bridge_name:        "whatsapp"   
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_telegram_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_telegram_bridge"
 | 
			
		||||
    database_name:      "mautrix_telegram_bridge"
 | 
			
		||||
    bridge_name:        "telegram"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_signal_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_signal_bridge"
 | 
			
		||||
    database_name:      "mautrix_signal_bridge"
 | 
			
		||||
    bridge_name:        "signal"
 | 
			
		||||
 | 
			
		||||
# Deactivated temporary, due to bug which is hard to find 
 | 
			
		||||
# @todo Reactivate 
 | 
			
		||||
#  - database_password:  "{{ applications[application_id].credentials.mautrix_slack_bridge_database_password }}"
 | 
			
		||||
#    database_username:  "mautrix_slack_bridge"
 | 
			
		||||
#    database_name:      "mautrix_slack_bridge"
 | 
			
		||||
#    bridge_name:        "slack"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_facebook_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_facebook_bridge"
 | 
			
		||||
    database_name:      "mautrix_facebook_bridge"
 | 
			
		||||
    bridge_name:        "facebook"
 | 
			
		||||
 | 
			
		||||
  - database_password:  "{{ applications[application_id].credentials.mautrix_instagram_bridge_database_password }}"
 | 
			
		||||
    database_username:  "mautrix_instagram_bridge"
 | 
			
		||||
    database_name:      "mautrix_instagram_bridge"
 | 
			
		||||
    bridge_name:        "instagram"
 | 
			
		||||
@@ -96,7 +96,7 @@
 | 
			
		||||
  shell: >
 | 
			
		||||
    docker compose exec web bash -c "
 | 
			
		||||
      cd /app &&
 | 
			
		||||
      RAILS_ENV=production bundle exec rails runner \"
 | 
			
		||||
      RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bundle exec rails runner \"
 | 
			
		||||
        user = User.find_by(mail: '{{ users.administrator.email }}');
 | 
			
		||||
        if user.nil?;
 | 
			
		||||
          puts 'User with email {{ users.administrator.email }} not found.';
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@
 | 
			
		||||
- name: Set settings in OpenProject
 | 
			
		||||
  shell: >
 | 
			
		||||
    docker compose exec web bash -c "cd /app &&
 | 
			
		||||
    RAILS_ENV=production bundle exec rails runner \"Setting[:{{ item.key }}] = '{{ item.value }}'\""
 | 
			
		||||
    RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bundle exec rails runner \"Setting[:{{ item.key }}] = '{{ item.value }}'\""
 | 
			
		||||
  args:
 | 
			
		||||
    chdir: "{{ docker_compose.directories.instance }}"
 | 
			
		||||
  loop: "{{ openproject_rails_settings | dict2items }}"
 | 
			
		||||
 
 | 
			
		||||
@@ -149,7 +149,7 @@ def update_mastodon():
 | 
			
		||||
    Runs the database migration for Mastodon to ensure all required tables are up to date.
 | 
			
		||||
    """
 | 
			
		||||
    print("Starting Mastodon database migration.")
 | 
			
		||||
    run_command("docker compose exec -T web bash -c 'RAILS_ENV=production bin/rails db:migrate'")
 | 
			
		||||
    run_command("docker compose exec -T web bash -c 'RAILS_ENV={{ CYMAIS_ENVIRONMENT | lower }} bin/rails db:migrate'")
 | 
			
		||||
    print("Mastodon database migration complete.")
 | 
			
		||||
 | 
			
		||||
def upgrade_listmonk():
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								tests/unit/test_bridge_filters.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								tests/unit/test_bridge_filters.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
import os
 | 
			
		||||
import sys
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
# Add the filter_plugins directory from the docker-matrix role to the import path
 | 
			
		||||
sys.path.insert(
 | 
			
		||||
    0,
 | 
			
		||||
    os.path.abspath(
 | 
			
		||||
        os.path.join(os.path.dirname(__file__), "../../roles/docker-matrix")
 | 
			
		||||
    ),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from filter_plugins.bridge_filters import filter_enabled_bridges
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestBridgeFilters(unittest.TestCase):
 | 
			
		||||
    def test_no_bridges_returns_empty_list(self):
 | 
			
		||||
        # When there are no bridges defined, result should be an empty list
 | 
			
		||||
        self.assertEqual(filter_enabled_bridges([], {}), [])
 | 
			
		||||
 | 
			
		||||
    def test_all_bridges_disabled(self):
 | 
			
		||||
        # Define two bridges, but plugins dict has them disabled or missing
 | 
			
		||||
        bridges = [
 | 
			
		||||
            {'bridge_name': 'whatsapp', 'config': {}},
 | 
			
		||||
            {'bridge_name': 'telegram', 'config': {}},
 | 
			
		||||
        ]
 | 
			
		||||
        plugins = {
 | 
			
		||||
            'whatsapp': False,
 | 
			
		||||
            'telegram': False,
 | 
			
		||||
        }
 | 
			
		||||
        result = filter_enabled_bridges(bridges, plugins)
 | 
			
		||||
        self.assertEqual(result, [])
 | 
			
		||||
 | 
			
		||||
    def test_some_bridges_enabled(self):
 | 
			
		||||
        # Only bridges with True in plugins should be returned
 | 
			
		||||
        bridges = [
 | 
			
		||||
            {'bridge_name': 'whatsapp', 'version': '1.0'},
 | 
			
		||||
            {'bridge_name': 'telegram', 'version': '1.0'},
 | 
			
		||||
            {'bridge_name': 'signal', 'version': '1.0'},
 | 
			
		||||
        ]
 | 
			
		||||
        plugins = {
 | 
			
		||||
            'whatsapp': True,
 | 
			
		||||
            'telegram': False,
 | 
			
		||||
            'signal': True,
 | 
			
		||||
        }
 | 
			
		||||
        result = filter_enabled_bridges(bridges, plugins)
 | 
			
		||||
        expected = [
 | 
			
		||||
            {'bridge_name': 'whatsapp', 'version': '1.0'},
 | 
			
		||||
            {'bridge_name': 'signal', 'version': '1.0'},
 | 
			
		||||
        ]
 | 
			
		||||
        self.assertEqual(result, expected)
 | 
			
		||||
 | 
			
		||||
    def test_bridge_without_plugin_entry_defaults_to_disabled(self):
 | 
			
		||||
        # If a bridge_name is not present in plugins, it should be treated as disabled
 | 
			
		||||
        bridges = [
 | 
			
		||||
            {'bridge_name': 'facebook', 'enabled': True},
 | 
			
		||||
        ]
 | 
			
		||||
        plugins = {}  # no entries
 | 
			
		||||
        result = filter_enabled_bridges(bridges, plugins)
 | 
			
		||||
        self.assertEqual(result, [])
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
if __name__ == "__main__":
 | 
			
		||||
    unittest.main()
 | 
			
		||||
@@ -1,6 +1,16 @@
 | 
			
		||||
# tests/unit/test_configuration_filters.py
 | 
			
		||||
 | 
			
		||||
import unittest
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
sys.path.insert(
 | 
			
		||||
    0,
 | 
			
		||||
    os.path.abspath(
 | 
			
		||||
        os.path.join(os.path.dirname(__file__), "../../")
 | 
			
		||||
    ),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from filter_plugins.configuration_filters import (
 | 
			
		||||
    is_feature_enabled,
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,16 @@
 | 
			
		||||
import unittest
 | 
			
		||||
import hashlib
 | 
			
		||||
import base64
 | 
			
		||||
import sys
 | 
			
		||||
import os
 | 
			
		||||
 | 
			
		||||
sys.path.insert(
 | 
			
		||||
    0,
 | 
			
		||||
    os.path.abspath(
 | 
			
		||||
        os.path.join(os.path.dirname(__file__), "../../")
 | 
			
		||||
    ),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from filter_plugins.csp_filters import FilterModule, AnsibleFilterError
 | 
			
		||||
 | 
			
		||||
class TestCspFilters(unittest.TestCase):
 | 
			
		||||
 
 | 
			
		||||
@@ -2,8 +2,12 @@ import os
 | 
			
		||||
import sys
 | 
			
		||||
import unittest
 | 
			
		||||
 | 
			
		||||
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__), "../../.."))
 | 
			
		||||
sys.path.insert(0, PROJECT_ROOT)
 | 
			
		||||
sys.path.insert(
 | 
			
		||||
    0,
 | 
			
		||||
    os.path.abspath(
 | 
			
		||||
        os.path.join(os.path.dirname(__file__), "../../")
 | 
			
		||||
    ),
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
from filter_plugins.redirect_filters import FilterModule
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user