diff --git a/config.xml b/config.xml
index 84f26ec..d59290b 100644
--- a/config.xml
+++ b/config.xml
@@ -1,4 +1,4 @@
-
+
ps_tech_vendor_boilerplate
@@ -6,6 +6,6 @@
- 0
- 1
-
+ 1
+ 0
+
\ No newline at end of file
diff --git a/e2e-env/README.md b/e2e-env/README.md
new file mode 100644
index 0000000..2b5c360
--- /dev/null
+++ b/e2e-env/README.md
@@ -0,0 +1,59 @@
+# PS Eventbus E2E Env
+
+## Table of Contents
+
+- [Introduction](#introduction)
+- [Installation](#installation)
+- [Usage](#usage)
+- [Contributions](#contributions)
+- [Licence](#licence)
+
+## Introduction
+
+Enabling the startup of a complete stack to perform E2E tests on `ps_eventbus`.
+stack consists of the following elements:
+
+- A storefront under Flashlight (with a mock of `ps_account` and a local link to `ps_eventbus`);
+- A MySQL database;
+- PHPMyAdmin;
+- A mock of the CloudSync APIs.
+
+For the CloudSync APIs mock, it is a NodeJS application simulating the CloudSync APIs. Requests made by `ps_eventbus` to CloudSync are redirected to the mock using a reverse proxy (nginx).
+When a request reaches the mock, it utilizes WebSockets to transmit the said request from `ps_eventbus` to the E2E tests, allowing validation of the information coming out of `ps_eventbus`.
+
+## Installation
+
+1. Clone the repository.:
+
+```bash
+git clone https://github.com/PrestaShopCorp/ps_eventbus.git
+cd ps_eventbus/e2e-env
+```
+
+2. Build the Docker configuration:
+
+```
+docker compose build --no-cache
+```
+
+3. start docker environment:
+
+```
+docker compose up
+```
+
+Or in detached mode:
+
+```
+docker compose up -d
+```
+
+Or specifically only starting PrestaShop (and its dependencies) with special commands to be sure your containers and volumes will be recreacted/renewed:
+
+```
+docker compose up prestashop --force-recreate --renew-anon-volumes
+```
+
+## Usage
+
+Once the stack is started under Docker, simply navigate to the e2e directory and run the E2E tests.
diff --git a/e2e-env/docker-compose.yml b/e2e-env/docker-compose.yml
new file mode 100644
index 0000000..a96d0af
--- /dev/null
+++ b/e2e-env/docker-compose.yml
@@ -0,0 +1,51 @@
+services:
+ prestashop:
+ image: ${DOCKER_IMAGE_PRESTASHOP:?See e2e-env/.env.dist}
+ depends_on:
+ mysql:
+ condition: service_healthy
+ volumes:
+ - ..:/var/www/html/modules/ps_tech_vendor_boilerplate:rw
+ - ./init-scripts:/tmp/init-scripts:ro
+ - /var/www/html/modules/ps_tech_vendor_boilerplate/vendor
+ - /var/www/html/modules/ps_tech_vendor_boilerplate/tools/vendor
+ environment:
+ - PS_DOMAIN=localhost:8000
+ - ON_INIT_SCRIPT_FAILURE=fail
+ - DEBUG_MODE=true
+ - INIT_SCRIPTS_USER=root
+ ports:
+ - ${HOST_PORT_BIND_PRESTASHOP:?See e2e-env/.env.dist}:80
+ networks:
+ - prestashop
+
+ mysql:
+ image: mariadb:${DOCKER_VERSION_MARIADB:?See e2e-env/.env.dist}
+ healthcheck:
+ test:
+ [
+ "CMD",
+ "mysqladmin",
+ "ping",
+ "--host=localhost",
+ "--user=prestashop",
+ "--password=prestashop",
+ ]
+ interval: 1s
+ timeout: 10s
+ retries: 30
+ environment:
+ - MYSQL_HOST=mysql
+ - MYSQL_USER=prestashop
+ - MYSQL_PASSWORD=prestashop
+ - MYSQL_ROOT_PASSWORD=prestashop
+ - MYSQL_PORT=3306
+ - MYSQL_DATABASE=prestashop
+ ports:
+ - ${HOST_PORT_BIND_MYSQL:?See e2e-env/.env.dist}:3306
+ networks:
+ - prestashop
+
+networks:
+ prestashop:
+ driver: bridge
diff --git a/e2e-env/init-scripts/install-module.sh b/e2e-env/init-scripts/install-module.sh
new file mode 100755
index 0000000..508ad94
--- /dev/null
+++ b/e2e-env/init-scripts/install-module.sh
@@ -0,0 +1,68 @@
+#!/bin/sh
+#
+# This is an init-script for prestashop-flashlight.
+#
+# Storing a folder in /var/www/html/modules is not enough to register the module
+# into PrestaShop, hence why we have to call the console install CLI.
+#
+set -eu
+
+MODULE_NAME="ps_tech_vendor_boilerplate"
+PS_EVENTBUS_VERSION="v3.0.8"
+
+error() {
+ printf "\e[1;31m%s\e[0m\n" "${1:-Unknown error}"
+ exit "${2:-1}"
+}
+
+run_user() {
+ sudo -g www-data -u www-data -- "$@"
+}
+
+ps_accounts_mock_install() {
+ echo "* [ps_accounts_mock] downloading..."
+ wget -q -O /tmp/ps_accounts.zip "https://github.com/PrestaShopCorp/ps_accounts_mock/releases/download/0.0.0/ps_accounts.zip"
+ echo "* [ps_accounts_mock] unziping..."
+ run_user unzip -qq /tmp/ps_accounts.zip -d /var/www/html/modules
+ echo "* [ps_accounts_mock] installing the module..."
+ cd "$PS_FOLDER"
+ run_user php -d memory_limit=-1 bin/console prestashop:module --no-interaction install "ps_accounts"
+}
+
+module_install() {
+ # Some explanations are required here:
+ #
+ # If you look closer to the ./docker-compose.yml prestashop service, you will
+ # see multiple mounts on the same files:
+ # - ..:/var/www/html/modules/ps_tech_vendor_boilerplate:rw => mount all the sources
+ # - /var/www/html/modules/ps_tech_vendor_boilerplate/vendor => void the specific vendor dir, makint it empty
+ # - /var/www/html/modules/ps_tech_vendor_boilerplate/tools/vendor => void the specific vendor dev dir, making it empty
+ #
+ # That said, we now want our container to have RW access on these directories,
+ # and to install the required composer dependencies for the module to work.
+ #
+ # Other scenarios could be imagined, but this is the best way to avoid writes on a mounted volume,
+ # which would not work on a Linux environment (binding a volume), as opposed to a Windows or Mac one (NFS mount).
+ chown www-data:www-data ./modules/$MODULE_NAME/vendor
+ chown www-data:www-data ./modules/$MODULE_NAME/tools/vendor
+ run_user composer install -n -d ./modules/$MODULE_NAME
+
+ echo "* [module_install] installing the module..."
+ cd "$PS_FOLDER"
+ run_user php -d memory_limit=-1 bin/console prestashop:module --no-interaction install "$MODULE_NAME"
+}
+
+ps_eventbus_Install() {
+ echo "* [ps_eventbus] downloading..."
+ wget -q -O /tmp/ps_eventbus.zip "https://github.com/PrestaShopCorp/ps_eventbus/releases/download/$PS_EVENTBUS_VERSION/ps_eventbus-$PS_EVENTBUS_VERSION.zip"
+ echo "* [ps_eventbus] unziping..."
+ run_user unzip -qq /tmp/ps_eventbus.zip -d /var/www/html/modules
+ echo "* [ps_eventbus] installing the module..."
+ cd "$PS_FOLDER"
+ run_user php -d memory_limit=-1 bin/console prestashop:module --no-interaction install "ps_eventbus"
+}
+
+ps_accounts_mock_install
+ps_eventbus_Install
+module_install
+
diff --git a/e2e-env/nginx.conf b/e2e-env/nginx.conf
new file mode 100644
index 0000000..9a0e5d9
--- /dev/null
+++ b/e2e-env/nginx.conf
@@ -0,0 +1,90 @@
+user nginx;
+worker_processes auto;
+
+error_log /dev/stdout notice;
+pid /var/run/nginx.pid;
+
+events {
+ worker_connections 1024;
+}
+
+http {
+ include /etc/nginx/mime.types;
+ default_type application/octet-stream;
+
+ log_format main escape=none '$remote_addr - $remote_user [$time_local] "$request" '
+ '$status $body_bytes_sent "$http_referer" '
+ '"$http_user_agent" "$http_x_forwarded_for" \n$request_body';
+
+ access_log /dev/stdout main;
+ rewrite_log on;
+ keepalive_timeout 65;
+ gzip on;
+
+ # @see http://nginx.org/en/docs/http/ngx_http_core_module.html#resolver
+ # @see https://medium.com/@huynhquangthao/how-does-the-docker-dns-work-ab69bde4c82a
+ resolver 127.0.0.11 ipv6=off valid=10s;
+ resolver_timeout 10s;
+
+ server {
+ location /collector/v1 {
+ set $backend "http://cloudsync-mock:3333";
+ rewrite /collector/v1/?(.*) /$1 break;
+ proxy_pass $backend;
+ }
+
+ # legacy alias to /collector
+ location /collector/ {
+ set $backend "http://cloudsync-mock:3333";
+ rewrite /collector/?(.*) /$1 break;
+ proxy_pass $backend;
+ }
+
+ location /sync/v1/ {
+ set $backend "http://cloudsync-mock:3232";
+ rewrite /sync/v1/?(.*) /$1 break;
+ proxy_pass $backend;
+ }
+
+ # legacy alias to /sync/v1
+ location /sync-api/ {
+ set $backend "http://cloudsync-mock:3232";
+ rewrite /sync-api/?(.*) /$1 break;
+ proxy_pass $backend;
+ }
+
+ location /live-sync-api/v1/ {
+ set $backend "http://cloudsync-mock:3434";
+ rewrite /live-sync-api/v1/?(.*) /$1 break;
+ proxy_pass $backend;
+ }
+
+ location /mock-probe/ {
+ set $backend "http://cloudsync-mock:8080";
+ proxy_http_version 1.1;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "Upgrade";
+ proxy_set_header Host $host;
+ proxy_pass $backend;
+ }
+
+ location /prestashop {
+ set $frontend "http://prestashop:80";
+ proxy_set_header Host "localhost:8000";
+ proxy_set_header X-Real-IP $remote_addr;
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
+ rewrite /prestashop/?(.*) /$1 break;
+ proxy_pass $frontend;
+ }
+
+ location /favicon.ico {
+ log_not_found off;
+ access_log off;
+ }
+
+ location /nginx_status {
+ stub_status on;
+ access_log off;
+ }
+ }
+}