diff --git a/.circleci/config.yml b/.circleci/config.yml index b9b5ceb95..b76de402e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,64 +1,231 @@ -version: 2.1 # CircleCI version -orbs: - sonarcloud: sonarsource/sonarcloud@1.1.1 +version: 2.1 + jobs: build: - machine: #Linux machine instead of docker environment + machine: image: ubuntu-2004:2024.05.1 docker_layer_caching: true - working_directory: ~/mentoring # Default working directory + + working_directory: ~/mentoring + steps: + # ------------------------------- + # Git setup + # ------------------------------- + - run: + name: Configure git to use HTTPS + command: git config --global url."https://github.com/".insteadOf "git@github.com:" + - checkout: path: ~/mentoring/ + + # ------------------------------- + # Restore mentoring dependencies + # ------------------------------- - restore_cache: key: mentoring-dependency-cache-{{ checksum "src/package.json" }} + - run: - name: Install dependencies - command: cd src/ && npm install #cd ../src/ && pwd && + name: Install mentoring dependencies + command: | + cd src + npm install + - save_cache: - key: mentoring-dependency-cache-{{checksum "src/package.json"}} + key: mentoring-dependency-cache-{{ checksum "src/package.json" }} paths: - ./src/node_modules + + # ------------------------------- + # Disable SSH rewrite + # ------------------------------- - run: - name: Executing unit test cases - command: cd src/ && npm run test -- --coverage --collectCoverageFrom="./services/**" - - store_artifacts: - path: src/coverage/ - destination: /coverage/ - - sonarcloud/scan + name: Disable SSH rewrite + command: git config --global --unset url."ssh://git@github.com".insteadOf || true + + # ------------------------------- + # Clone USER service + # ------------------------------- - run: - name: Checking prerequisites - command: |- - docker-compose --version - - run: - name: Cloning user service - command: cd ../ && git clone https://github.com/ELEVATE-Project/user.git --branch dev --single-branch + name: Clone User service + command: | + cd .. + git clone https://github.com/ELEVATE-Project/user.git \ + --branch develop \ + --single-branch + - restore_cache: key: user-dependency-cache-{{ checksum "../user/src/package.json" }} + - run: name: Install User service dependencies - command: cd ../user/src/ && npm install #cd ../src/ && pwd && + command: | + cd ../user/src + npm install + - save_cache: - key: user-dependency-cache-{{checksum "../user/src/package.json"}} + key: user-dependency-cache-{{ checksum "../user/src/package.json" }} paths: - ../user/src/node_modules + + # ------------------------------- + # Clone optional services + # ------------------------------- + - run: + name: Clone Scheduler service + command: | + cd .. + git clone https://github.com/ELEVATE-Project/scheduler.git \ + --branch dev \ + --single-branch || true + + - run: + name: Clone Communications service + command: | + cd .. + git clone https://github.com/ELEVATE-Project/chat-communications.git \ + --branch dev \ + --single-branch || true + + # ------------------------------- + # Config + # ------------------------------- + - run: + name: Copy config.json + command: cp dev-ops/integration_test.config.json src/config.json + + # ------------------------------- + # Start docker-compose + # ------------------------------- + - run: + name: Start docker containers + command: | + cd dev-ops + docker-compose pull || true + docker-compose build + docker-compose up -d + sleep 20 + + # ------------------------------- + # Wait for healthchecks + # ------------------------------- + - run: + name: Wait for services to be healthy + command: | + cd dev-ops + echo "Waiting for containers to be healthy..." + + for i in {1..30}; do + unhealthy=$(docker ps --filter "health=unhealthy" --format "{{.Names}}") + starting=$(docker ps --filter "health=starting" --format "{{.Names}}") + + if [ -z "$unhealthy" ] && [ -z "$starting" ]; then + echo "All containers are healthy" + break + fi + + echo "Waiting... attempt $i" + docker ps --format "table {{.Names}}\t{{.Status}}" + sleep 5 + done + # ------------------------------- + # Run migrations (EXPLICIT) + # ------------------------------- + - run: + name: Run mentoring migrations + command: | + export MENTORING=$(docker ps --format "{{.Names}}" | grep mentoring) + echo "Running migrations in $MENTORING" + docker exec "$MENTORING" npm run db:init + + - run: + name: Enable Citus and run distributionColumns.psql + command: | + cd dev-ops + set -e + + echo "Enabling Citus extension..." + docker-compose exec -T citus psql \ + -U postgres \ + -d elevate-mentoring \ + -c "CREATE EXTENSION IF NOT EXISTS citus;" + + echo "Running distributionColumns.psql..." + docker-compose exec -T citus psql \ + -U postgres \ + -d elevate-mentoring \ + -f /var/src/distributionColumns.psql + + echo "Citus setup completed." + + # ------------------------------- + # Run seeders (EXPLICIT) + # ------------------------------- + - run: + name: Run mentoring seeders + command: | + export MENTORING=$(docker ps --format "{{.Names}}" | grep mentoring) + echo "Running seeders in $MENTORING" + docker exec "$MENTORING" npm run db:seed:all + + - run: + name: Start mentoring app + command: | + export MENTORING=$(docker ps --format "{{.Names}}" | grep mentoring) + echo "Starting mentoring app..." + docker exec -d "$MENTORING" npm run dev + + - run: + name: Run user migrations + command: | + export USER=$(docker ps --format "{{.Names}}" | grep user) + echo "Running user migrations in $USER" + docker exec "$USER" npm run db:init + + - run: + name: Run user seeders + command: | + export USER=$(docker ps --format "{{.Names}}" | grep user) + docker exec "$USER" npm run db:seed:all + + + - run: + name: Start user service + command: | + export USER=$(docker ps --format "{{.Names}}" | grep user) + echo "Starting user service..." + docker exec -d "$USER" npm run dev + + + # ------------------------------- + # Run integration tests + # ------------------------------- - run: - name: Starting the docker containers - command: |- - cd dev-ops/ && docker-compose up -d + name: Run integration tests + command: | + cd src + npm run test:integration + + # ------------------------------- + # Diagnostics + # ------------------------------- - run: - name: Running test cases - command: |- - cd src/ && npm run test:integration + name: Print logs on failure + when: always + command: | + cd dev-ops + docker-compose logs --tail=200 kafka || true + docker-compose logs --tail=200 citus || true + docker-compose logs --tail=200 mentoring || true + docker-compose logs --tail=200 user || true + - store_test_results: path: ./dev-ops/report + workflows: - build-and-test: # This is the name of the workflow, - # Inside the workflow, you define the jobs you want to run. + build-and-test: jobs: - build: - context: - - SonarCloud filters: tags: - only: \b(dev|develop|main)\b + only: \b(dev|develop|main)\b \ No newline at end of file diff --git a/dev-ops/docker-compose.yml b/dev-ops/docker-compose.yml index 55d9dea25..4b4fc31a6 100644 --- a/dev-ops/docker-compose.yml +++ b/dev-ops/docker-compose.yml @@ -1,101 +1,133 @@ version: '3' services: + + redis: + image: 'redis:7.0.0' + restart: 'always' + ports: + - '6379:6379' + networks: + - elevate_net + logging: + driver: local + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 5s + timeout: 5s + retries: 20 + zookeeper: - image: 'bitnami/zookeeper:3.8.0' + image: 'confluentinc/cp-zookeeper:7.3.0' ports: - '2181:2181' environment: - - ALLOW_ANONYMOUS_LOGIN=yes + - ZOOKEEPER_CLIENT_PORT=2181 + - ZOOKEEPER_TICK_TIME=2000 networks: - elevate_net - volumes: - - zookeeper-data:/bitnami/zookeeper logging: driver: none + kafka: - image: 'bitnami/kafka:3.1.0' + image: 'confluentinc/cp-kafka:7.3.0' ports: - '9092:9092' environment: - - KAFKA_BROKER_ID=1 - - KAFKA_CFG_LISTENERS=CLIENT://:9092,EXTERNAL://:9093 - - KAFKA_CFG_ADVERTISED_LISTENERS=CLIENT://kafka:9092,EXTERNAL://localhost:9093 - - KAFKA_CFG_ZOOKEEPER_CONNECT=zookeeper:2181 - - ALLOW_PLAINTEXT_LISTENER=yes - - KAFKA_CFG_LISTENER_SECURITY_PROTOCOL_MAP=CLIENT:PLAINTEXT,EXTERNAL:PLAINTEXT - - KAFKA_CFG_INTER_BROKER_LISTENER_NAME=CLIENT + KAFKA_BROKER_ID: 1 + KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 + # Listeners configured for CI internal docker networking + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:9093 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT + KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 depends_on: - zookeeper networks: - elevate_net - volumes: - - kafka-data:/bitnami/kafka + healthcheck: + test: kafka-topics --bootstrap-server localhost:9092 --list || exit 1 + interval: 10s + timeout: 30s + retries: 10 logging: - driver: none - mongo: - image: 'mongo:4.4.14' - restart: 'always' - ports: - - '27017:27017' - networks: - - elevate_net + driver: local + + citus: + image: citusdata/citus:13.0 + container_name: citus_db volumes: - - mongo-data:/data/db - logging: - driver: none - redis: - image: 'redis:7.0.0' - restart: 'always' - expose: - - '6379' + - ../src/distributionColumns.psql:/var/src/distributionColumns.psql + ports: + - '5432:5432' + environment: + POSTGRES_USER: 'postgres' + POSTGRES_PASSWORD: 'postgres' + POSTGRES_HOST_AUTH_METHOD: 'trust' networks: - elevate_net - logging: - driver: none + healthcheck: + test: ['CMD-SHELL', 'pg_isready -U postgres'] + interval: 10s + timeout: 5s + retries: 5 + mentoring: - build: '../' - image: elevate/mentoring:1.0 + build: '../' + image: elevate/mentoring:2.4 volumes: - ../src/:/var/src ports: - '3000:3000' - command: [ 'node', 'app.js' ] environment: - - MONGODB_URL=mongodb://mongo:27017/elevate-mentoring - KAFKA_URL=kafka:9092 - - USER_SERIVCE_HOST=http://user:3001 + - USER_SERVICE_HOST=http://user:3001 - REDIS_HOST=redis://redis:6379 + - SCHEDULER_SERVICE_HOST=http://scheduler:4000 + - DEV_DATABASE_URL=postgres://postgres:postgres@citus:5432/elevate-mentoring + - ENABLE_CHAT=false + - ADMIN_SECRET_CODE=ADMIN_SECRET_CODE depends_on: - - kafka - - mongo + kafka: + condition: service_healthy + citus: + condition: service_healthy + redis: + condition: service_healthy networks: - elevate_net env_file: - - integration_test.mentoring.env + - ./integration_test.mentoring.env + user: - build: '../../user/' - image: elevate/user:1.0 + build: '../../user/' + image: elevate/user:2.4 volumes: - ../../user/src/:/var/src ports: - '3001:3001' - command: [ 'nodemon', 'app.js' ] environment: - - MONGODB_URL=mongodb://mongo:27017/elevate-mentoring - KAFKA_URL=kafka:9092 - REDIS_HOST=redis://redis:6379 + - SCHEDULER_SERVICE_HOST=http://scheduler:4000 + - DEV_DATABASE_URL=postgres://postgres:postgres@citus:5432/mentoring_user + - ENABLE_EMAIL_OTP_VERIFICATION=false + - ADMIN_SECRET_CODE=ADMIN_SECRET_CODE depends_on: - - kafka - - mongo - - redis + kafka: + condition: service_healthy + citus: + condition: service_healthy + redis: + condition: service_healthy networks: - elevate_net env_file: - - integration_test.user.env + - ./integration_test.user.env + networks: elevate_net: external: false + volumes: zookeeper-data: - kafka-data: - mongo-data: + kafka-data: \ No newline at end of file diff --git a/dev-ops/integration_test.config.json b/dev-ops/integration_test.config.json new file mode 100644 index 000000000..789b6dc22 --- /dev/null +++ b/dev-ops/integration_test.config.json @@ -0,0 +1,11 @@ +{ + "authTokenUserInformation": { + "id": "data.id", + "name": "data.name", + "organization_code": "data.organizations[?id={{organization_id}}].code", + "organization_id": "data.organization_ids[0]", + "organizations": "data.organizations", + "roles": "data.organizations[?id={{organization_id}}].roles", + "tenant_code": "data.tenant_code" + } +} \ No newline at end of file diff --git a/dev-ops/integration_test.mentoring.env b/dev-ops/integration_test.mentoring.env index 408981b17..f7f9cc2b0 100644 --- a/dev-ops/integration_test.mentoring.env +++ b/dev-ops/integration_test.mentoring.env @@ -1,124 +1,71 @@ +#Token secret to verify the access token +ACCESS_TOKEN_SECRET = 'bsj82AHBxahusub12yexlashsbxAXADHBlaj' # Mentoring Service Config - +ALLOWED_HOST="*" +APPLICATION_ENV = development +APPLICATION_HOST="localhost" # Port on which service runs APPLICATION_PORT = 3000 +# Big blue button base url +BIB_BLUE_BUTTON_BASE_URL = /bigbluebutton/ -#Service environment -APPLICATION_ENV = development - -#Route after base url -APPLICATION_BASE_URL = /mentoring/ - -#Mongo db connectivity url -MONGODB_URL = mongodb://localhost:27017/elevate-mentoring - -#Token secret to verify the access token -ACCESS_TOKEN_SECRET = 'bsj82AHBxahusub12yexlashsbxAXADHBlaj' - -# Internal access token for communicationcation between services via network call -INTERNAL_ACCESS_TOKEN = 'internal-access-token' - -# Kafka hosted server url -KAFKA_URL = localhost:9092 - -# Kafka group to which consumer belongs -KAFKA_GROUP_ID = userservice +# Big blue button secret key +BIG_BLUE_BUTTON_SECRET_KEY = n -# Kafka topic to push notification data -NOTIFICATION_KAFKA_TOPIC = 'testTopic' +BIG_BLUE_BUTTON_SESSION_END_URL = 'session_end_url' -# Kafka topic name to consume from mentoring topic -KAFKA_MENTORING_TOPIC ="mentoringtopic" +# Big blue button url +BIG_BLUE_BUTTON_URL = https://dev.mentoring.shikshalokam.org -# Kafka topic to push recording data -KAFKA_RECORDING_TOPIC ="recordingtopic" +#######CACHE_ENABLED = false +#######CACHE_SHARDS= 32 # Any one of three features available for cloud storage CLOUD_STORAGE = 'GCP/AWS/AZURE' +CLOUD_STORAGE_ACCOUNTNAME = '****' +CLOUD_STORAGE_BUCKETNAME = '****' +CLOUD_STORAGE_BUCKET_TYPE = '****' +CLOUD_STORAGE_PROJECT = "CLOUD_STORAGE_PROJECT" +CLOUD_STORAGE_PROVIDER = "gcloud" +CLOUD_STORAGE_SECRET = "CLOUD_STORAGE_SECRET" -# Gcp json config file path -GCP_PATH = 'gcp.json' - -# Gcp bucket name which stores files -DEFAULT_GCP_BUCKET_NAME = 'gcp-bucket-storage-name' - -# Gcp project id -GCP_PROJECT_ID = 'project-id' - -# Aws access key id -AWS_ACCESS_KEY_ID = 'aws-access-key-id' - -# Aws secret access key -AWS_SECRET_ACCESS_KEY = 'aws-secret-access-key' - -# Aws region where bucket will be located -AWS_BUCKET_REGION = 'ap-south-1' - -# Aws end point -AWS_BUCKET_ENDPOINT = 's3.ap-south-1.amazonaws.com' - -# Aws bucket name which stores files -DEFAULT_AWS_BUCKET_NAME = 'aws-bucket-storage-name' - -# Azure storage account name -AZURE_ACCOUNT_NAME = 'account-name' - -# Azure storage account key -AZURE_ACCOUNT_KEY = 'azure-account-key' - -# Azure storage container which stores files -DEFAULT_AZURE_CONTAINER_NAME = 'azure-container-storage-name' - -#user serice host -USER_SERIVCE_HOST = 'http://localhost:3001' - -#user serice base url -USER_SERIVCE_BASE_URL = '/user/' - -# Big blue button url -BIG_BLUE_BUTTON_URL = https://dev.mentoring.shikshalokam.org - -# Big blue button base url -BIB_BLUE_BUTTON_BASE_URL = /bigbluebutton/ +COMMUNICATION_SERVICE_HOST="http://localhost:3123" +DEFAULT_MEETING_SERVICE="BBB" +DEFAULT_ORGANISATION_CODE="default_code" +DEFAULT_ORGANIZATION_CODE="default_code" +DEFAULT_ORG_ID=1 +DEFAULT_TENANT_CODE="default" +DEV_DATABASE_URL=postgres://postgres:postgres@citus:5432/elevate-mentoring +EMAIL_ID_ENCRYPTION_IV="c9c7bd480494409071847264652f5c95" +EMAIL_ID_ENCRYPTION_KEY="eef7e009626c18724be86afa41a2620e0718561a508c61f92d7ee0377177ef7b" +ENABLE_CHAT="false" +EVENTS_TOPIC="dev.userCreate" +# Internal access token for communicationcation between services via network call +INTERNAL_ACCESS_TOKEN = 'internal_access_token' +IS_AUTH_TOKEN_BEARER="false" +# Kafka group to which consumer belongs +KAFKA_GROUP_ID = qa.mentoring +KAFKA_TOPIC="qa.topic" +# Kafka hosted server url +KAFKA_URL = kafka:9092 +LIMIT_FOR_SESSION_REQUEST_MONTH = 1 # Meeting end callback events end point MEETING_END_CALLBACK_EVENTS = https%3A%2F%2Fdev.elevate-apis.shikshalokam.org%2Fmentoring%2Fv1%2Fsessions%2Fcompleted - -# Big blue button secret key -BIG_BLUE_BUTTON_SECRET_KEY = n - +MENTOR_ACCEPT_SESSION_REQUEST_EMAIL_TEMPLATE="request_session_accepted_email_template" +MENTOR_REJECT_SESSION_REQUEST_EMAIL_TEMPLATE="request_session_rejected_email_template" +# Kafka topic to push notification data +NOTIFICATION_KAFKA_TOPIC = 'testTopic' +PORTAL_BASE_URL = "PORTAL_BASE_URL" +PUBLIC_ASSET_BUCKETNAME="PUBLIC_ASSET_BUCKETNAME" +RATING_KAFKA_TOPIC="RATING_KAFKA_TOPIC" # Big blue button recording ready callback url RECORDING_READY_CALLBACK_URL = http%3A%2F%2Flocalhost%3A3000%2F%3FmeetingID%3Dmeet123 - -#Enable logging of network request -ENABLE_LOG = true - - -# Api doc url -API_DOC_URL = '/api-doc' - -#Internal cache expiry time -INTERNAL_CACHE_EXP_TIME = 86400 - # Redis Host connectivity url -REDIS_HOST = 'redis://localhost:6379' - -#Kafka internal communicationcation -CLEAR_INTERNAL_CACHE = 'mentoringInternal' - -#Enable email for reported issue. -ENABLE_EMAIL_FOR_REPORT_ISSUE = true - -#Email id of the support team. -SUPPORT_EMAIL_ID = 'support@xyz.com,team@xyz.com' - -#Email template code for reported issue. -REPORT_ISSUE_EMAIL_TEMPLATE_CODE = 'user_issue_reported' - -BIG_BLUE_BUTTON_SESSION_END_URL = 'somethi' - -ERROR_LOG_LEVEL='silly' -DISABLE_LOG=false -DEFAULT_MEETING_SERVICE="BBB" -SESSION_EDIT_WINDOW_MINUTES=0 -SESSION_MENTEE_LIMIT=0 +REDIS_HOST = 'redis://redis:6379' +SCHEDULER_SERVICE_ERROR_REPORTING_EMAIL_ID="rakesh.k@pacewisdom.com" +SCHEDULER_SERVICE_HOST="SCHEDULER_SERVICE_HOST" +SCHEDULER_SERVICE_URL = "SCHEDULER_SERVICE_URL" +SESSION_MENTEE_LIMIT = "5" +SUPPORT_EMAIL_ID="support@shikshalokam.org" +USER_SERVICE_HOST="http://user:3001" \ No newline at end of file diff --git a/dev-ops/integration_test.user.env b/dev-ops/integration_test.user.env index 00d03612e..c3044ea9b 100644 --- a/dev-ops/integration_test.user.env +++ b/dev-ops/integration_test.user.env @@ -1,117 +1,83 @@ -#User Service Config - -# Port on which service runs -APPLICATION_PORT = 3001 - -# Service environment -APPLICATION_ENV = development - -# Database connectivity url -MONGODB_URL = mongodb://mongo:27017/elevate-mentoring - # Token secret to generate access token ACCESS_TOKEN_SECRET = 'bsj82AHBxahusub12yexlashsbxAXADHBlaj' +ADMIN_INVITEE_UPLOAD_EMAIL_TEMPLATE_CODE +ADMIN_SECRET_CODE +ALLOWED_HOST = '*' -# Token secret to generate refresh token -REFRESH_TOKEN_SECRET = 'refresh-token-secret' - -# Kafka hosted server url -KAFKA_URL = localhost:9092 +# Api doc url +API_DOC_URL = '/api-doc' +APPLICATION_BASE_URL = "/user" +# Service environment +APPLICATION_ENV = development +APPLICATION_HOST="localhost" +# Port on which service runs +APPLICATION_PORT = 3001 +APP_NAME = 'user' +CAPTCHA_ENABLE=false + +CLOUD_STORAGE = 'GCP/AWS/AZURE' +CLOUD_STORAGE_ACCOUNTNAME = '****' +CLOUD_STORAGE_BUCKETNAME = '****' +CLOUD_STORAGE_BUCKET_TYPE = '****' +CLOUD_STORAGE_PROJECT = "CLOUD_STORAGE_PROJECT" +CLOUD_STORAGE_PROVIDER = "gcloud" +CLOUD_STORAGE_SECRET = "CLOUD_STORAGE_SECRET" + +DEFAULT_ORGANISATION_CODE = "default_code" + +DEFAULT_ORG_ID=1 +DEFAULT_ROLE="mentor,mentee" +DEFAULT_TENANT_ORG_CODE="default_code" +DEFAULT_TENANT_ORG_NAME="Default Organization" +DEV_DATABASE_URL=postgres://postgres:postgres@citus:5432/mentoring_user +EMAIL_ID_ENCRYPTION_IV="c9c7bd480494409071847264652f5c95" +EMAIL_ID_ENCRYPTION_KEY="eef7e009626c18724be86afa41a2620e0718561a508c61f92d7ee0377177ef7b" +ENTITY_MANAGEMENT_SERVICE_BASE_URL="http://localhost:3000/mentoring/" +EVENT_ENABLE_ORG_KAFKA_EVENTS = true +EVENT_ENABLE_TENANT_KAFKA_EVENTS = true +EVENT_ENABLE_USER_KAFKA_EVENTS = true +EVENT_ORGANIZATION_KAFKA_TOPIC = "dev.organizationEvent" +EVENT_ORG_LISTENER_URLS="http://localhost:3000/mentoring/v1/organization/eventListener" +EVENT_TENANT_KAFKA_TOPIC="dev.tenantEvent" +EVENT_USER_KAFKA_TOPIC="dev.userCreate" +# Internal access token for communicationcation between services via network call +INTERNAL_ACCESS_TOKEN = 'internal_access_token' +#Internal cache expiry time +INTERNAL_CACHE_EXP_TIME = 86400 +INVITEE_EMAIL_TEMPLATE_CODE="invite_user" +IS_AUTH_TOKEN_BEARER=false +IV="2lIctRkqzYMWbwlW1jCC9A==" # Kafka group to which consumer belongs -KAFKA_GROUP_ID = userservice - +KAFKA_GROUP_ID = qa.users # Kafka topic to consume data from -KAFKA_TOPIC = 'testTopic' - +KAFKA_TOPIC = 'qa.topic' +# Kafka hosted server url +KAFKA_URL = kafka:9092 +KEY="g5MQ7HG/r5gPCPQQCwfBBEduAt72ewJIY/gWc0RNoak=" +MENTORING_SERVICE_URL="http://localhost:3000" # Kafka topic to push notification data NOTIFICATION_KAFKA_TOPIC = 'testTopic' - -# Any one of three features available for cloud storage -CLOUD_STORAGE = 'AWS' - -# Gcp json config file path -GCP_PATH = 'gcp.json' - -# Gcp bucket name which stores files -DEFAULT_GCP_BUCKET_NAME = 'gcp-bucket-storage-name' - -# Gcp project id -GCP_PROJECT_ID = 'project-id' - -# Aws access key id -AWS_ACCESS_KEY_ID = 'aws-access-key-id' - -# Aws secret access key -AWS_SECRET_ACCESS_KEY = 'aws-secret-access-key' - -# Aws region where bucket will be located -AWS_BUCKET_REGION = 'ap-south-1' - -# Aws end point -AWS_BUCKET_ENDPOINT = 's3.ap-south-1.amazonaws.com' - -# Aws bucket name which stores files -DEFAULT_AWS_BUCKET_NAME = 'aws-bucket-storage-name' - -# Azure storage account name -AZURE_ACCOUNT_NAME = 'account-name' - -# Azure storage account key -AZURE_ACCOUNT_KEY = 'azure-account-key' - -# Azure storage container which stores files -DEFAULT_AZURE_CONTAINER_NAME = 'azure-container-storage-name' - -# Internal access token for communicationcation between services via network call -INTERNAL_ACCESS_TOKEN = 'internal-access-token' - -#Enable logging of network request -ENABLE_LOG = true - -# JWT Access Token expiry In Days -ACCESS_TOKEN_EXPIRY = '1' - -# JWT Refresh Token expiry In Days -REFRESH_TOKEN_EXPIRY = '183' - -# Redis Host connectivity url -REDIS_HOST = 'redis://localhost:6379' - +OTP_EMAIL_TEMPLATE_CODE = 'ssss' # Otp expiration time for forgetpassword or registration process OTP_EXP_TIME = 86400 - -# Enable email based otp verification for registration process -ENABLE_EMAIL_OTP_VERIFICATION = false - -# Api doc url -API_DOC_URL = '/api-doc' - -#Enable email for reported issue. -ENABLE_EMAIL_FOR_REPORT_ISSUE = true - -#Email id of the support team. -SUPPORT_EMAIL_ID = 'support@xyz.com,team@xyz.com' - -#Email template code for reported issue. -REPORT_ISSUE_EMAIL_TEMPLATE_CODE = 'user_issue_reported' - -#Internal cache expiry time -INTERNAL_CACHE_EXP_TIME = 86400 - -#Kafka internal communicationcation -CLEAR_INTERNAL_CACHE = 'userInternal' - -APP_NAME = 'user' - +PASSWORD_POLICY_MESSAGE = "Password must have at least two uppercase letters, two numbers, three special characters, and be at least 11 characters long." +PORTAL_URL="PORTAL_URL" +PUBLIC_ASSET_BUCKETNAME=PUBLIC_ASSET_BUCKETNAME +RATING_KAFKA_TOPIC = "dev.mentor_rating" +RECAPTCHA_SECRET_KEY=RECAPTCHA_SECRET_KEY +REDIS_HOST = 'redis://redis:6379' +REFRESH_TOKEN_EXPIRY="7" +# Token secret to generate refresh token +REFRESH_TOKEN_SECRET = 'refresh-token-secret' +REFRESH_VIEW_INTERVAL= 30000 REGISTRATION_EMAIL_TEMPLATE_CODE = 'code' - -OTP_EMAIL_TEMPLATE_CODE = 'ssss' -REDIS_CACHE_EXP_TIME = 11 - -KEY="g5MQ7HG/r5gPCPQQCwfBBEduAt72ewJIY/gWc0RNoak=" -IV="2lIctRkqzYMWbwlW1jCC9A==" - -ERROR_LOG_LEVEL='silly' -DISABLE_LOG=false -SESSION_MENTEE_LIMIT=0 +REGISTRATION_OTP_EMAIL_TEMPLATE_CODE= "registrationotp" +SALT_ROUNDS = "10" +SAMPLE_CSV_FILE_PATH="sample/bulk_user_creation.csv" +SCHEDULER_SERVICE_BASE_URL="/scheduler/" +SCHEDULER_SERVICE_ERROR_REPORTING_EMAIL_ID = "rakesh.k@pacewisdom.com" +SCHEDULER_SERVICE_HOST="http://localhost:3567" +SCHEDULER_SERVICE_URL="http://localhost:3567/jobs/scheduleJob" +SERVICE_NAME = "UserService" +SIGNED_URL_EXPIRY_IN_SECONDS = "900" \ No newline at end of file diff --git a/src/configs/kafka.js b/src/configs/kafka.js index 8ddf12406..73e015be6 100644 --- a/src/configs/kafka.js +++ b/src/configs/kafka.js @@ -44,79 +44,132 @@ module.exports = async () => { } async function startConsumer(kafkaClient) { - const consumer = kafkaClient.consumer({ groupId: process.env.KAFKA_GROUP_ID }) + const consumer = kafkaClient.consumer({ + groupId: process.env.KAFKA_GROUP_ID, + sessionTimeout: 45000, // allows slow handlers + heartbeatInterval: 3000, + }) + + consumer.on(consumer.events.GROUP_JOIN, (e) => { + logger.info(`Kafka Consumer: Group join – partitions assigned = ${JSON.stringify(e.payload?.memberAssignment)}`) + }) + + consumer.on(consumer.events.REBALANCING, (e) => { + logger.warn(`Kafka Consumer: Rebalancing triggered – ${e.payload.reason}`) + }) + + consumer.on(consumer.events.HEARTBEAT, () => { + logger.debug('Kafka Consumer: Heartbeat OK') + }) await consumer.connect() + logger.info('Kafka Consumer: Connected to broker') const topics = [process.env.EVENTS_TOPIC, process.env.CLEAR_INTERNAL_CACHE].filter(Boolean) + await consumer.subscribe({ topics }) + logger.info(`Kafka Consumer: Subscribed to topics = ${JSON.stringify(topics)}`) await consumer.run({ - eachMessage: async ({ topic, partition, message }) => { - try { + autoCommit: true, // safe because processing is fast per message + eachBatch: async ({ batch, heartbeat, resolveOffset, commitOffsetsIfNecessary, isRunning, isStale }) => { + logger.info( + `Kafka Batch: Received batch | topic=${batch.topic} | partition=${batch.partition} | size=${batch.messages.length}` + ) + + for (const message of batch.messages) { + if (!isRunning() || isStale()) { + logger.warn('Kafka Batch: Consumer is no longer running or batch is stale, stopping processing.') + break + } + const rawValue = message.value?.toString() const offset = message.offset + const topic = batch.topic + const partition = batch.partition + + logger.info(`Kafka Batch: Message | topic=${topic} | partition=${partition} | offset=${offset}`) if (!rawValue) { - logger.warn(`Empty Kafka message skipped on topic ${topic}`) - return + logger.warn(`Kafka Batch: Empty message skipped`) + resolveOffset(offset) + continue } let payload try { payload = JSON.parse(rawValue) } catch (e) { - logger.warn('Invalid JSON in Kafka message; skipping', { - topic, - partition, + logger.warn('Kafka Batch: Invalid JSON, skipping', { offset, - err: e?.message, + err: e.message, }) - return + resolveOffset(offset) + continue } + //-------------------------------------------------------- + // ROUTE MESSAGE TO CORRECT HANDLER + //-------------------------------------------------------- let response - if (payload && topic === process.env.EVENTS_TOPIC) { - // Handle organization events - if ( - payload.entity === 'organization' && - (payload.eventType === 'create' || - payload.eventType === 'update' || - payload.eventType === 'deactivate') - ) { - response = await organizationConsumer.messageReceived(payload) - } - if (payload.entity === 'user') { - if (payload.eventType === 'roleChange') { - response = await rolechangeConsumer.messageReceived(payload) - } - if (payload.eventType === 'create' || payload.eventType === 'bulk-create') { - response = await createuserConsumer.messageReceived(payload) - } - if (payload.eventType === 'delete') { - response = await deleteuserConsumer.messageReceived(payload) + try { + if (topic === process.env.EVENTS_TOPIC && payload) { + // Handle organization events + if ( + payload.entity === 'organization' && + (payload.eventType === 'create' || + payload.eventType === 'update' || + payload.eventType === 'deactivate') + ) { + response = await organizationConsumer.messageReceived(payload) } - if (payload.eventType === 'update' || payload.eventType === 'bulk-update') { - response = await updateuserConsumer.messageReceived(payload) + + // Handle user events + if (payload.entity === 'user') { + if (payload.eventType === 'roleChange') { + response = await rolechangeConsumer.messageReceived(payload) + } + + if (payload.eventType === 'create' || payload.eventType === 'bulk-create') { + response = await createuserConsumer.messageReceived(payload) + } + + if (payload.eventType === 'delete') { + response = await deleteuserConsumer.messageReceived(payload) + } + + if (payload.eventType === 'update' || payload.eventType === 'bulk-update') { + response = await updateuserConsumer.messageReceived(payload) + } } - } - } - if (payload && topic === process.env.CLEAR_INTERNAL_CACHE) { - if (payload.type === 'CLEAR_INTERNAL_CACHE') { + } else if (topic === process.env.CLEAR_INTERNAL_CACHE && payload?.type === 'CLEAR_INTERNAL_CACHE') { response = await utils.internalDel(payload.value) } + + logger.info(`Kafka event handling response: ${response}`) + } catch (handlerErr) { + logger.error(`Kafka Batch: Error handling message`, { + topic, + partition, + offset, + err: handlerErr.stack || handlerErr.message, + }) } - logger.info(`Kafka event handling response : ${response}`) - } catch (err) { - logger.error(`Error in Kafka message handler for topic ${topic}`, { - topic, - partition, - offset, - err: err?.stack || err?.message || String(err), - }) + //-------------------------------------------------------- + // MARKS MESSAGE AS PROCESSED + //-------------------------------------------------------- + resolveOffset(offset) + + //-------------------------------------------------------- + // HEARTBEAT TO PREVENT TIMEOUT + //-------------------------------------------------------- + await heartbeat() } + + // commit offsets once per batch + await commitOffsetsIfNecessary() }, }) } diff --git a/src/database/migrations/20251020081719-add-orgEntity-type.js b/src/database/migrations/20251020081719-add-orgEntity-type.js index c095015b1..1bcaea75f 100644 --- a/src/database/migrations/20251020081719-add-orgEntity-type.js +++ b/src/database/migrations/20251020081719-add-orgEntity-type.js @@ -28,8 +28,6 @@ module.exports = { updated_by: 0, allow_filtering: false, organization_id: defaultOrgId, - organization_code: defaultOrgCode, - tenant_code: defaultTenantCode, has_entities: false, meta: JSON.stringify({ label: convertToWords(key), diff --git a/src/distributionColumns.psql b/src/distributionColumns.psql index e7746237c..4b5bed3b6 100644 --- a/src/distributionColumns.psql +++ b/src/distributionColumns.psql @@ -1,9 +1,11 @@ +SELECT create_reference_table('entity_types'); +SELECT create_reference_table('permissions'); +SELECT create_reference_table('sessions'); SELECT create_distributed_table('availabilities', 'tenant_code'); SELECT create_distributed_table('connection_requests', 'tenant_code'); SELECT create_distributed_table('connections', 'tenant_code'); SELECT create_distributed_table('default_rules', 'tenant_code'); SELECT create_distributed_table('entities', 'tenant_code'); -SELECT create_distributed_table('entity_types', 'tenant_code'); SELECT create_distributed_table('feedbacks', 'tenant_code'); SELECT create_distributed_table('file_uploads', 'tenant_code'); SELECT create_distributed_table('forms', 'tenant_code'); @@ -21,8 +23,6 @@ SELECT create_distributed_table('resources', 'tenant_code'); SELECT create_distributed_table('role_extensions', 'tenant_code'); SELECT create_distributed_table('session_attendees', 'tenant_code'); SELECT create_distributed_table('session_request', 'tenant_code'); -SELECT create_distributed_table('sessions', 'tenant_code'); SELECT create_distributed_table('user_extensions', 'tenant_code'); -SELECT create_distributed_table('permissions', 'id'); SELECT create_distributed_table('role_permission_mapping', 'role_title'); diff --git a/src/integration-tests-new/admin/admin.spec.js b/src/integration-tests-new/admin/admin.spec.js new file mode 100644 index 000000000..db5a4e010 --- /dev/null +++ b/src/integration-tests-new/admin/admin.spec.js @@ -0,0 +1,70 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/admin.schemas.json') + +describe('admin endpoints generated from api-doc.yaml', () => { + describe('DELETE /mentoring/v1/admin/userDelete', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/admin/userDelete` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_admin_userDelete'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/admin/triggerViewRebuild', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/admin/triggerViewRebuild` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_admin_triggerViewRebuild'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/admin/triggerViewRebuildInternal', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/admin/triggerViewRebuildInternal` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_admin_triggerViewRebuildInternal'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/admin/triggerPeriodicViewRefresh', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/admin/triggerPeriodicViewRefresh` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_admin_triggerPeriodicViewRefresh'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/admin/triggerPeriodicViewRefreshInternal', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/admin/triggerPeriodicViewRefreshInternal` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_admin_triggerPeriodicViewRefreshInternal'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/admin/schemas/admin.schemas.json b/src/integration-tests-new/admin/schemas/admin.schemas.json new file mode 100644 index 000000000..fd10a0a54 --- /dev/null +++ b/src/integration-tests-new/admin/schemas/admin.schemas.json @@ -0,0 +1,155 @@ +{ + "DELETE_mentoring_v1_admin_userDelete": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "isAttendeesNotified": { + "type": "boolean" + }, + "areUserDetailsCleared": { + "type": "boolean" + }, + "isUnenrolledFromSessions": { + "type": "boolean" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_admin_triggerViewRebuild": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_admin_triggerViewRebuildInternal": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_admin_triggerPeriodicViewRefresh": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_admin_triggerPeriodicViewRefreshInternal": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/cloud-services/cloud-services.spec.js b/src/integration-tests-new/cloud-services/cloud-services.spec.js new file mode 100644 index 000000000..90237c5f5 --- /dev/null +++ b/src/integration-tests-new/cloud-services/cloud-services.spec.js @@ -0,0 +1,31 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/cloud-services.schemas.json') + +describe('cloud-services endpoints generated from api-doc.yaml', () => { + describe('GET /mentoring/v1/cloud-services/getSignedUrl', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/cloud-services/getSignedUrl` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_cloud-services_getSignedUrl'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/cloud-services/getDownloadableUrl', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/cloud-services/getDownloadableUrl` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_cloud-services_getDownloadableUrl'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/cloud-services/schemas/cloud-services.schemas.json b/src/integration-tests-new/cloud-services/schemas/cloud-services.schemas.json new file mode 100644 index 000000000..f06891a7e --- /dev/null +++ b/src/integration-tests-new/cloud-services/schemas/cloud-services.schemas.json @@ -0,0 +1,29 @@ +{ + "GET_mentoring_v1_cloud-services_getSignedUrl": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "signed_url": { + "type": "string" + }, + "file_path": { + "type": "string" + }, + "dest_file_path": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_cloud-services_getDownloadableUrl": {} +} diff --git a/src/integration-tests-new/commonTests.js b/src/integration-tests-new/commonTests.js new file mode 100644 index 000000000..d2b55c1a5 --- /dev/null +++ b/src/integration-tests-new/commonTests.js @@ -0,0 +1,212 @@ +var supertest = require('supertest') //require supertest +var defaults = require('superagent-defaults') +const { faker } = require('@faker-js/faker') +const crypto = require('crypto') +const common = require('@constants/common') +let baseURL = 'http://localhost:3000' +//supertest hits the HTTP server (your app) +let defaultHeaders +let admin_secret_code = process.env.ADMIN_SECRET_CODE || 'ADMIN_SECRET_CODE' + +const logIn = async () => { + try { + let request = defaults(supertest('http://localhost:3001')) + let waitOn = require('wait-on') + let opts = { + resources: [baseURL], + delay: 1000, // initial delay in ms, default 0 + interval: 1000, // poll interval in ms, default 250ms + timeout: 60000, + } + await waitOn(opts) + let email = 'adithya' + crypto.randomBytes(5).toString('hex') + '@tunerlabs.com' + let password = faker.internet.password() + let res = await request.post('/user/v1/account/create').set('origin', 'localhost').send({ + name: 'adithya', + email: email, + password: 'PassworD@@@123', + role: common.MENTEE_ROLE, + }) + + res = await request.post('/user/v1/account/login').set('origin', 'localhost').send({ + identifier: email, + password: 'PassworD@@@123', + }) + + await waitForProfileExtension(res.body.result.access_token) + + if (res.body.result.access_token && res.body.result.user.id) { + defaultHeaders = { + 'x-auth-token': 'bearer ' + res.body.result.access_token, + Connection: 'keep-alive', + 'Content-Type': 'application/json', + } + global.request = defaults(supertest(baseURL)) + global.request.set(defaultHeaders) + global.userId = res.body.result.user.id + + const userDetails = { + token: res.body.result.access_token, + refreshToken: res.body.result.refresh_token, + userId: res.body.result.user.id, + email: email, + password: password, + organizations: res.body.result.user.organizations, + } + + return userDetails + } else { + console.error('Error while getting access token') + return false + } + } catch (error) { + console.error(error) + } +} +const mentorLogIn = async () => { + try { + let request = defaults(supertest('http://localhost:3001')) + var waitOn = require('wait-on') + var opts = { + resources: [baseURL], + delay: 1000, // initial delay in ms, default 0 + interval: 500, // poll interval in ms, default 250ms + timeout: 30000, + } + await waitOn(opts) + let email = 'nevil' + crypto.randomBytes(5).toString('hex') + '@tunerlabs.com' + let password = faker.internet.password() + + let res = await request.post('/user/v1/account/create').set('origin', 'localhost').send({ + name: 'Nevil', + email: email, + password: 'PassworD@@@123', + isAMentor: true, + secretCode: 'secret-code', + }) + + res = await request.post('/user/v1/account/login').set('origin', 'localhost').send({ + identifier: email, + password: 'PassworD@@@123', + }) + await waitForProfileExtension(res.body.result.access_token) + if (res.body.result.access_token && res.body.result.user.id) { + defaultHeaders = { + 'x-auth-token': 'bearer ' + res.body.result.access_token, + Connection: 'keep-alive', + 'Content-Type': 'application/json', + } + global.request = defaults(supertest(baseURL)) + global.request.set(defaultHeaders) + global.userId = res.body.result.user.id + + const mentorDetails = { + token: res.body.result.access_token, + refreshToken: res.body.result.refresh_token, + userId: res.body.result.user.id, + email: email, + password: password, + organizations: res.body.result.user.organizations, + } + + return mentorDetails + } else { + console.error('Error while getting access token') + return false + } + } catch (error) { + console.error(error) + } +} +const adminLogin = async () => { + try { + let request = defaults(supertest('http://localhost:3001')) + var waitOn = require('wait-on') + var opts = { + resources: [baseURL], + delay: 1000, // initial delay in ms, default 0 + interval: 500, // poll interval in ms, default 250ms + timeout: 30000, + } + await waitOn(opts) + let email = 'system' + crypto.randomBytes(5).toString('hex') + '@admin.com' + let password = 'PASSword###11' + + let adminCreate = await request + .post('/user/v1/admin/create') + .set('internal_access_token', 'internal_access_token') //NOTE: Please replace {{internal_access_token}} with your actual token + .send({ + name: 'system', + email: email, + password: password, + secret_code: admin_secret_code, + }) + + let res = await request.post('/user/v1/admin/login').set('origin', 'localhost').send({ + identifier: email, + password: password, + }) + await waitForProfileExtension(res.body.result.access_token) + if (res.body.result.access_token && res.body.result.user.id) { + defaultHeaders = { + 'x-auth-token': 'bearer ' + res.body.result.access_token, + Connection: 'keep-alive', + 'Content-Type': 'application/json', + } + global.request = defaults(supertest(baseURL)) + global.request.set(defaultHeaders) + global.userId = res.body.result.user.id + + const adminDetails = { + token: res.body.result.access_token, + refreshToken: res.body.result.refresh_token, + userId: res.body.result.user.id, + email: email, + password: password, + organizations: res.body.result.user.organizations, + } + + return adminDetails + } else { + console.error('Error while getting access token') + return false + } + } catch (error) { + console.error(error) + } +} +function logError(res) { + let successCodes = [200, 201, 202] + if (!successCodes.includes(res.statusCode)) { + console.log('Response Body', res.body) + } +} + +const waitForProfileExtension = async (token, timeoutMs = 15000) => { + const start = Date.now() + + while (Date.now() - start < timeoutMs) { + try { + let request = defaults(supertest('http://localhost:3000')) + const res = await request + .get(`/mentoring/v1/profile/getExtension`) + .set('x-auth-token', token) + .set('origin', 'localhost') + + if (res.status === 200 && res.body && res.body.result) { + return res.body.result + } + } catch (error) {} + + await new Promise((r) => setTimeout(r, 300)) + } + + throw new Error('Profile extension not ready within timeout') +} + +module.exports = { + logIn, //-- export if token is generated + logError, + mentorLogIn, + adminLogin, +} diff --git a/src/integration-tests-new/config/config.spec.js b/src/integration-tests-new/config/config.spec.js new file mode 100644 index 000000000..072c42e37 --- /dev/null +++ b/src/integration-tests-new/config/config.spec.js @@ -0,0 +1,17 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/config.schemas.json') + +describe('config endpoints generated from api-doc.yaml', () => { + describe('GET /mentoring/v1/config/get', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/config/get` + let req = request(BASE).get(url) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_config_get'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/config/schemas/config.schemas.json b/src/integration-tests-new/config/schemas/config.schemas.json new file mode 100644 index 000000000..2da66807b --- /dev/null +++ b/src/integration-tests-new/config/schemas/config.schemas.json @@ -0,0 +1,58 @@ +{ + "GET_mentoring_v1_config_get": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "meeting_platform": { + "type": "string" + }, + "report_issue": { + "type": "object", + "properties": { + "to": { + "type": "string" + }, + "subject": { + "type": "string" + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "forms_version": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + } + } + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/connections/connections.specs.js b/src/integration-tests-new/connections/connections.specs.js new file mode 100644 index 000000000..20fc9540e --- /dev/null +++ b/src/integration-tests-new/connections/connections.specs.js @@ -0,0 +1,97 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') + +const schemas = require('./schemas/connections.schemas.json') + +beforeAll(async () => { + console.log('Attempting to login...') + adminDetails = await commonHelper.adminLogin() +}) + +describe('connections endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/connections/initiate', () => { + test('should return 200', async () => { + const menteeDetails = await commonHelper.logIn() + const mentorDetails = await commonHelper.mentorLogIn() + + const url = `/mentoring/v1/connections/initiate` + let req = request(BASE).post(url) + req = req.set('x-auth-token', menteeDetails.token) // Mentee initiates + req = req + .send({ + user_id: mentorDetails.userId.toString(), // With mentor + message: 'Hi, I would like to connect with you.', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_connections_initiate'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/connections/accept', () => { + test('should return 200', async () => { + const menteeDetails = await commonHelper.logIn() + const mentorDetails = await commonHelper.mentorLogIn() + // Step 1: Mentee initiates a connection with Mentor + const initiateRes = await request(BASE) + .post('/mentoring/v1/connections/initiate') + .set('x-auth-token', menteeDetails.token) + .send({ + user_id: mentorDetails.userId.toString(), + message: 'Hi, please accept my connection request.', + }) + expect(initiateRes.status).toBe(201) + + // Step 2: Mentor accepts the connection from Mentee + const url = `/mentoring/v1/connections/accept` + let req = request(BASE).post(url) + req = req.set('x-auth-token', mentorDetails.token) // Mentor accepts + req = req + .send({ + user_id: menteeDetails.userId.toString(), // From mentee + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_connections_accept'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/connections/reject', () => { + test('should return 200', async () => { + const menteeDetails = await commonHelper.logIn() + const mentorDetails = await commonHelper.mentorLogIn() + // Step 1: Mentee initiates a connection with Mentor + const initiateRes = await request(BASE) + .post('/mentoring/v1/connections/initiate') + .set('x-auth-token', menteeDetails.token) + .send({ + user_id: mentorDetails.userId.toString(), + message: 'Hi, I am sending a request to be rejected.', + }) + expect(initiateRes.status).toBe(201) + + // Step 2: Mentor rejects the connection from Mentee + const url = `/mentoring/v1/connections/reject` + let req = request(BASE).post(url) + req = req.set('x-auth-token', mentorDetails.token) // Mentor rejects + req = req + .send({ + user_id: menteeDetails.userId.toString(), // From mentee + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_connections_reject'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/connections/schemas/connections.schemas.json b/src/integration-tests-new/connections/schemas/connections.schemas.json new file mode 100644 index 000000000..5b1e2f013 --- /dev/null +++ b/src/integration-tests-new/connections/schemas/connections.schemas.json @@ -0,0 +1,586 @@ +{ + "POST_mentoring_v1_connections_initiate": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "id": { + "type": "number" + }, + "user_id": { + "type": "string" + }, + "friend_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_connections_pending": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "user_id": { + "type": "string" + }, + "friend_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "message": { + "type": "string" + } + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "updated_by": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "user_details": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "mentee_visibility": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "designation": { + "type": "null" + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "string" + }, + "experience": { + "type": "null" + }, + "is_mentor": { + "type": "boolean" + }, + "image": { + "type": "string" + }, + "communications_user_id": { + "type": "string" + } + } + } + } + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_connections_list": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "mentee_visibility": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "designation": { + "type": "null" + }, + "experience": { + "type": "null" + }, + "is_mentor": { + "type": "boolean" + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "string" + }, + "image": { + "type": "string" + }, + "communications_user_id": { + "type": "string" + } + } + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_connections_getInfo": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "user_id": { + "type": "string" + }, + "friend_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "room_id": { + "type": "string" + } + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "updated_by": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "user_details": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "mentee_visibility": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "designation": { + "type": "null" + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "string" + }, + "is_mentor": { + "type": "boolean" + }, + "experience": { + "type": "null" + }, + "image": { + "type": "string" + }, + "communications_user_id": { + "type": "string" + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_connections_reject": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_connections_accept": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "user_id": { + "type": "string" + }, + "friend_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "room_id": { + "type": "string" + } + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "updated_by": { + "type": "string" + }, + "created_by": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/default-rule/default-rule.specs.js b/src/integration-tests-new/default-rule/default-rule.specs.js new file mode 100644 index 000000000..9399c6c56 --- /dev/null +++ b/src/integration-tests-new/default-rule/default-rule.specs.js @@ -0,0 +1,177 @@ +jest.setTimeout(30000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') + +const schemas = require('./schemas/default-rule.schemas.json') + +let adminDetails = null +let testEntityTypeValue = null +let createdRuleId = null + +beforeAll(async () => { + adminDetails = await commonHelper.adminLogin() + + // Create a unique entity type for this test run + //make it unique using random alphabets not numbers + testEntityTypeValue = 'entityTypeForRule' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const createEntityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .send({ + value: testEntityTypeValue, + label: 'Test Entity Type for Rules', + data_type: 'STRING', + model_names: ['UserExtension'], + required: true, // As per your requirement + allow_filtering: true, + }) + expect(createEntityTypeRes.status).toBe(201) +}) + +describe('default-rule endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/default-rule/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/default-rule/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req + .send({ + type: 'session', + target_field: testEntityTypeValue, + is_target_from_sessions_mentor: true, + requester_field: testEntityTypeValue, + operator: 'equals', + requester_roles: ['session_manager'], + requester_roles_config: { + exclude: true, + }, + }) + .set('Content-Type', 'application/json') + + const res = await req + expect(res.status).toBe(201) + createdRuleId = res.body.result.id // Save the ID for update/delete tests + expect(res.status).toBe(201) + // validate response schema + expect(res.body).toMatchSchema(schemas['POST_mentoring_v1_default-rule_create']) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/default-rule/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/default-rule/read', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/default-rule/read` + const res = await request(BASE).get(url).set('x-auth-token', adminDetails.token) + expect(res.status).toBe(200) + // validate response schema + expect(res.body).toMatchSchema(schemas['GET_mentoring_v1_default-rule_read']) + }) + }) + + describe('PATCH /mentoring/v1/default-rule/update/{id}', () => { + test('should return 200 on successful update', async () => { + // Step 1: Create a unique entity type for the update test + const entityTypeForUpdate = + 'entityTypeForUpdate' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const createEntityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .send({ + value: entityTypeForUpdate, + label: 'Test Entity Type for Rule Update', + data_type: 'STRING', + model_names: ['UserExtension'], + required: true, + allow_filtering: true, + }) + expect(createEntityTypeRes.status).toBe(201) + + // Step 2: Create a default rule to be updated + const createRuleRes = await request(BASE) + .post('/mentoring/v1/default-rule/create') + .set('x-auth-token', adminDetails.token) + .send({ + type: 'session', + target_field: entityTypeForUpdate, + is_target_from_sessions_mentor: true, + requester_field: entityTypeForUpdate, + operator: 'equals', + requester_roles: ['session_manager'], + requester_roles_config: { exclude: true }, + }) + expect(createRuleRes.status).toBe(201) + const ruleIdToUpdate = createRuleRes.body.result.id + + // Step 3: Update the created rule + const url = `/mentoring/v1/default-rule/update/${ruleIdToUpdate}` + let req = request(BASE).patch(url).set('x-auth-token', adminDetails.token) + req = req + .send({ + type: 'session', + target_field: entityTypeForUpdate.toLocaleLowerCase(), + requester_field: entityTypeForUpdate.toLocaleLowerCase(), + // Using a different operator for update + operator: 'notEquals', + requester_roles_config: { exclude: false }, + is_target_from_sessions_mentor: true, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + // validate response schema + expect(res.body).toMatchSchema(schemas['PATCH_mentoring_v1_default-rule_update_id']) + }) + }) + + describe('DELETE /mentoring/v1/default-rule/delete/{id}', () => { + test('should return 200 on successful deletion', async () => { + // Step 1: Create a unique entity type for the delete test + const entityTypeForDelete = + 'entityTypeForDelete' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const createEntityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .send({ + value: entityTypeForDelete, + label: 'Test Entity Type for Rule Deletion', + data_type: 'STRING', + model_names: ['UserExtension'], + required: true, + allow_filtering: true, + }) + expect(createEntityTypeRes.status).toBe(201) + + // Step 2: Create a default rule to be deleted + const createRuleRes = await request(BASE) + .post('/mentoring/v1/default-rule/create') + .set('x-auth-token', adminDetails.token) + .send({ + type: 'session', + target_field: entityTypeForDelete, + is_target_from_sessions_mentor: true, + requester_field: entityTypeForDelete, + operator: 'equals', + requester_roles: ['session_manager'], + requester_roles_config: { exclude: true }, + }) + expect(createRuleRes.status).toBe(201) + const ruleIdToDelete = createRuleRes.body.result.id + + // Step 3: Delete the created rule + const url = `/mentoring/v1/default-rule/delete/${ruleIdToDelete}` + const res = await request(BASE).delete(url).set('x-auth-token', adminDetails.token) + expect(res.status).toBe(202) + // validate response schema + expect(res.body).toMatchSchema(schemas['DELETE_mentoring_v1_default-rule_delete_id']) + }) + }) +}) diff --git a/src/integration-tests-new/default-rule/schemas/default-rule.schemas.json b/src/integration-tests-new/default-rule/schemas/default-rule.schemas.json new file mode 100644 index 000000000..a42b6b79f --- /dev/null +++ b/src/integration-tests-new/default-rule/schemas/default-rule.schemas.json @@ -0,0 +1,355 @@ +{ + "POST_mentoring_v1_default-rule_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "target_field": { + "type": "string" + }, + "is_target_from_sessions_mentor": { + "type": "boolean" + }, + "requester_field": { + "type": "string" + }, + "operator": { + "type": "string" + }, + "requester_roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "requester_roles_config": { + "type": "object", + "properties": { + "exclude": { + "type": "boolean" + } + } + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "field_configs": { + "type": "null" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_default-rule_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "target_field": { + "type": "string" + }, + "is_target_from_sessions_mentor": { + "type": "boolean" + }, + "requester_field": { + "type": "string" + }, + "field_configs": { + "type": "null" + }, + "matching_operator": { + "type": "string" + }, + "requester_roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "role_config": { + "type": "object", + "properties": { + "exclude": { + "type": "boolean" + } + } + }, + "organization_id": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "PATCH_mentoring_v1_default-rule_update_id": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "target_field": { + "type": "string" + }, + "is_target_from_sessions_mentor": { + "type": "boolean" + }, + "requester_field": { + "type": "string" + }, + "field_configs": { + "type": "null" + }, + "operator": { + "type": "string" + }, + "requester_roles": { + "type": "array", + "items": { + "type": "string" + } + }, + "requester_roles_config": { + "type": "object", + "properties": { + "exclude": { + "type": "boolean" + } + } + }, + "organization_id": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_default-rule_delete_id": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/entity-type/entity-type.specs.js b/src/integration-tests-new/entity-type/entity-type.specs.js new file mode 100644 index 000000000..9495013ee --- /dev/null +++ b/src/integration-tests-new/entity-type/entity-type.specs.js @@ -0,0 +1,156 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +let menteeDetails = null // This user will make the request +let mentorDetails = null // This user will be the requestee +let adminDetails = null // Admin user if needed + +const schemas = require('./schemas/entity-type.schemas.json') + +beforeAll(async () => { + console.log('setting up global variables....') + // Log in both a mentee and a mentor for the test + menteeDetails = await commonHelper.logIn() + mentorDetails = await commonHelper.mentorLogIn() + adminDetails = await commonHelper.adminLogin() +}) + +describe('entity-type endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/entity-type/create', () => { + test('should return 201', async () => { + let value = 'string' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + + console.log('Creating entity type with value:', value) + const url = `/mentoring/v1/entity-type/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + req = req.set('timezone', 'Asia/Calcutta') + req = req + .send({ + value: value, // need unique value so concatenate with more characters which are alphabets and not numbers + label: 'String', + allow_filtering: true, + data_type: 'STRING', + model_names: ['UserExtension'], + required: true, + status: 'string', + type: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_entity-type_create'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/entity-type/read', () => { + // Note: The endpoint name suggests GET, but the implementation requires POST. + test('should return 200 on success', async () => { + const url = `/mentoring/v1/entity-type/read` + let req = request(BASE).post(url) + req = req.set('x-auth-token', mentorDetails.token) + req = req.set('org-id', mentorDetails.organizations[0].id.toString()) + req = req.set('timezone', 'Asia/Calcutta') + // This endpoint expects a body with the values to read, similar to the QA curl command. + req = req.send({ value: ['string', 'designation'] }) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_entity-type_read'] + if (!schema) throw new Error('Schema not found for GET_mentoring_v1_entity-type_read') + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/entity-type/update/{id}', () => { + test('should return 200 on success', async () => { + //const url = `/mentoring/v1/entity-type/update/1` // Use a real or placeholder ID + // First, create an entity type to update + const value = 'updateTestEntity' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const createRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: value, + label: 'Test Label', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + + expect(createRes.status).toBe(201) + const entityTypeId = createRes.body.result.id + + // Now, update the created entity type + const url = `/mentoring/v1/entity-type/update/${entityTypeId}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + req = req.set('timezone', 'Asia/Calcutta') + + // Update payload + req = req + .send({ + value: value, + label: 'string', + status: 'INACTIVE', + type: 'string', + data_type: 'STRING', + model_names: ['Session'], + allow_filtering: true, + required: true, + }) + .set('Content-Type', 'application/json') + const res = await req + //change to greater than equal to 202 exact + expect(res.status).toBe(202) + + // validate response schema + if (!schemas['POST_mentoring_v1_entity-type_update_id']) + throw new Error('Schema not found for POST_mentoring_v1_entity-type_update_id') + const schema = schemas['POST_mentoring_v1_entity-type_update_id'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/entity-type/delete/{id}', () => { + test('should return 200 on success', async () => { + //const url = `/mentoring/v1/entity-type/delete/1` // Use a real or placeholder ID + // First, create an entity type to delete + const value = 'deleteTestEntity' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const createRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: value, + label: 'Test Label for Deletion', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + + expect(createRes.status).toBe(201) + const entityTypeId = createRes.body.result.id + + // Now, delete the created entity type + const url = `/mentoring/v1/entity-type/delete/${entityTypeId}` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + req = req.set('timezone', 'Asia/Calcutta') + const res = await req + expect(res.status).toBe(202) + // validate response schema + if (!schemas['DELETE_mentoring_v1_entity-type_delete_id']) + throw new Error('Schema not found for DELETE_mentoring_v1_entity-type_delete_id') + const schema = schemas['DELETE_mentoring_v1_entity-type_delete_id'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/entity-type/schemas/entity-type.schemas.json b/src/integration-tests-new/entity-type/schemas/entity-type.schemas.json new file mode 100644 index 000000000..83b30c74f --- /dev/null +++ b/src/integration-tests-new/entity-type/schemas/entity-type.schemas.json @@ -0,0 +1,269 @@ +{ + "POST_mentoring_v1_entity-type_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "allow_filtering": { + "type": "boolean" + }, + "data_type": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "has_entities": { + "type": "boolean" + } + } + }, + "field_0": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_entity-type_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "entity_types": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "value": { "type": "string" }, + "label": { "type": "string" }, + "status": { "type": "string" }, + "created_by": { "type": "string" }, + "updated_by": { "type": "string" }, + "allow_filtering": { "type": "boolean" }, + "data_type": { "type": "string" }, + "organization_id": { "type": "string" }, + "parent_id": { "type": ["null", "number"] }, + "allow_custom_entities": { "type": "boolean" }, + "has_entities": { "type": "boolean" }, + "model_names": { + "type": "array", + "items": { "type": "string" } + }, + "required": { "type": "boolean" }, + "regex": { "type": "null" }, + "report_filter": { "type": "boolean" }, + "meta": { "type": "null" }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "deleted_at": { "type": "null" }, + "entities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "entity_type_id": { "type": "number" }, + "value": { "type": "string" }, + "label": { "type": "string" }, + "status": { "type": "string" }, + "type": { "type": "string" }, + "created_by": { "type": "string" }, + "updated_by": { "type": ["null", "string"] }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "deleted_at": { "type": "null" } + }, + "required": [ + "id", + "entity_type_id", + "value", + "label", + "status", + "type", + "created_by", + "updated_by", + "created_at", + "updated_at", + "deleted_at" + ] + } + } + }, + "required": [ + "id", + "value", + "label", + "status", + "created_by", + "updated_by", + "allow_filtering", + "data_type", + "organization_id", + "parent_id", + "allow_custom_entities", + "has_entities", + "model_names", + "required", + "regex", + "report_filter", + "meta", + "created_at", + "updated_at", + "deleted_at", + "entities" + ] + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_entity-type_update_id": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "value": { "type": "string" }, + "label": { "type": "string" }, + "status": { "type": "string" }, + "created_by": { "type": "string" }, + "updated_by": { "type": "string" }, + "allow_filtering": { "type": "boolean" }, + "data_type": { "type": "string" }, + "organization_id": { "type": "string" }, + "parent_id": { "type": "null" }, + "allow_custom_entities": { "type": "boolean" }, + "has_entities": { "type": "boolean" }, + "model_names": { + "type": "array", + "items": { "type": "string" } + }, + "required": { "type": "boolean" }, + "regex": { "type": "null" }, + "report_filter": { "type": "boolean" }, + "meta": { "type": "null" }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "deleted_at": { "type": "null" } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { "type": "string" }, + "meetingPlatform": { "type": "string" } + } + } + } + }, + "DELETE_mentoring_v1_entity-type_delete_id": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/entity/entity.specs.js b/src/integration-tests-new/entity/entity.specs.js new file mode 100644 index 000000000..ea99229af --- /dev/null +++ b/src/integration-tests-new/entity/entity.specs.js @@ -0,0 +1,206 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +let menteeDetails = null +let mentorDetails = null +let adminDetails = null +const schemas = require('./schemas/entity.schemas.json') + +beforeAll(async () => { + menteeDetails = await commonHelper.logIn() + mentorDetails = await commonHelper.mentorLogIn() + adminDetails = await commonHelper.adminLogin() +}) + +describe('entity endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/entity/create', () => { + test('should return 201', async () => { + // First, create an entity-type to associate the entity with + let entityValue = 'newEntityType' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const entityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: entityValue, + label: 'Test Entity Type', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + expect(entityTypeRes.status).toBe(201) + const entityTypeId = entityTypeRes.body.result.id + + const url = `/mentoring/v1/entity/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + req = req + .send({ + value: 'en', + label: 'English', + entity_type_id: entityTypeId, + type: 'SYSTEM', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_/mentoring/v1/entity/create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/entity/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('PUT /mentoring/v1/entity/update/{id}', () => { + test('should return 202', async () => { + let value = 'updateEntity' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + // Create entity type + const entityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: value, + label: 'Update Test', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + + expect(entityTypeRes.status).toBe(201) + const entityTypeId = entityTypeRes.body.result.id + + // Create entity + const entityRes = await request(BASE) + .post('/mentoring/v1/entity/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ value: 'initial_val', label: 'Initial Label', entity_type_id: entityTypeId, type: 'SYSTEM' }) + + expect(entityRes.status).toBe(201) + const entityId = entityRes.body.result.id + + const url = `/mentoring/v1/entity/update/${entityId}` + let req = request(BASE).put(url) + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + req = req + .send({ + value: 'updatedvalNew', + label: 'Updated Label', + status: 'ACTIVE', + entity_type_id: entityTypeId, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['PUT_/mentoring/v1/entity/update/{id}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/entity/update/999` // Some non-existent ID + const res = await request(BASE).put(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/entity/read/{id}', () => { + test('should return 200', async () => { + // Create entity type + let value = 'readEntityType' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + const entityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: value, + label: 'Read Test', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + expect(entityTypeRes.status).toBe(201) + const entityTypeId = entityTypeRes.body.result.id + + // Create entity + const entityRes = await request(BASE) + .post('/mentoring/v1/entity/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ value: 'read_val', label: 'Read Label', entity_type_id: entityTypeId, type: 'SYSTEM' }) + expect(entityRes.status).toBe(201) + const entityId = entityRes.body.result.id + + const url = `/mentoring/v1/entity/read/${entityId}` + let req = request(BASE).post(url) + //change menteedetails to admin token + req = req.set('x-auth-token', adminDetails.token) + req = req.set('org-id', adminDetails.organizations[0].id.toString()) + + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_/mentoring/v1/entity/read/{id}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/entity/read/string` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('DELETE /mentoring/v1/entity/delete/{id}', () => { + test('should return 202', async () => { + let value = 'deleteEntityType' + Math.random().toString(36).substring(2).replace(/[0-9]/g, '') + // Create entity type + const entityTypeRes = await request(BASE) + .post('/mentoring/v1/entity-type/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ + value: value, + label: 'Delete Test', + data_type: 'STRING', + model_names: ['UserExtension'], + status: 'ACTIVE', + }) + expect(entityTypeRes.status).toBe(201) + const entityTypeId = entityTypeRes.body.result.id + + // Create entity + const entityRes = await request(BASE) + .post('/mentoring/v1/entity/create') + .set('x-auth-token', adminDetails.token) + .set('org-id', adminDetails.organizations[0].id.toString()) + .send({ value: 'delete_val', label: 'Delete Label', entity_type_id: entityTypeId, type: 'SYSTEM' }) + expect(entityRes.status).toBe(201) + const entityId = entityRes.body.result.id + + const url = `/mentoring/v1/entity/delete/${entityId}` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', adminDetails.token) + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['DELETE_/mentoring/v1/entity/delete/{id}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/entity/delete/999` // Some non-existent ID + const res = await request(BASE).delete(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/entity/schemas/entity.schemas.json b/src/integration-tests-new/entity/schemas/entity.schemas.json new file mode 100644 index 000000000..cba324f77 --- /dev/null +++ b/src/integration-tests-new/entity/schemas/entity.schemas.json @@ -0,0 +1,216 @@ +{ + "POST_/mentoring/v1/entity/create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "type": { + "type": "string" + }, + "entity_type_id": { + "type": "number" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "PUT_/mentoring/v1/entity/update/{id}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "entity_type_id": { "type": "number" }, + "value": { "type": "string" }, + "label": { "type": "string" }, + "status": { "type": "string" }, + "type": { "type": "string" }, + "created_by": { "type": "string" }, + "updated_by": { "type": "string" }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "deleted_at": { "type": "null" } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_/mentoring/v1/entity/read/{id}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "entity_type_id": { "type": "number" }, + "value": { "type": "string" }, + "label": { "type": "string" }, + "status": { "type": "string" }, + "type": { "type": "string" }, + "created_by": { "type": "string" }, + "updated_by": { "type": ["string", "null"] }, + "created_at": { "type": "string" }, + "updated_at": { "type": "string" }, + "deleted_at": { "type": "null" } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_/mentoring/v1/entity/delete/{id}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/feedback/feedback.spec.js b/src/integration-tests-new/feedback/feedback.spec.js new file mode 100644 index 000000000..a2d3848e0 --- /dev/null +++ b/src/integration-tests-new/feedback/feedback.spec.js @@ -0,0 +1,54 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/feedback.schemas.json') + +describe('feedback endpoints generated from api-doc.yaml', () => { + describe('GET /mentoring/v1/feedback/forms/{SessionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/feedback/forms/1` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_/mentoring/v1/feedback/forms/{SessionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/feedback/forms/1` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/feedback/submit/{SessionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/feedback/submit/1` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + feedbacks: [ + { + question_id: '1', + value: '1', + }, + ], + feedback_as: 'mentee', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_/mentoring/v1/feedback/submit/{SessionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/feedback/submit/1` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/feedback/schemas/feedback.schemas.json b/src/integration-tests-new/feedback/schemas/feedback.schemas.json new file mode 100644 index 000000000..775105ec1 --- /dev/null +++ b/src/integration-tests-new/feedback/schemas/feedback.schemas.json @@ -0,0 +1,90 @@ +{ + "GET_/mentoring/v1/feedback/forms/{SessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "form": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "options": { + "type": "null" + }, + "type": { + "type": "string" + }, + "no_of_stars": { + "type": "number" + }, + "status": { + "type": "string" + }, + "category": { + "type": "null" + }, + "rendering_data": { + "type": "object", + "properties": { + "validators": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + } + } + }, + "disable": { + "type": "boolean" + }, + "visible": { + "type": "boolean" + }, + "class": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": {} + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "label": { + "type": "string" + } + } + } + } + } + }, + "meta": { + "type": "object", + "properties": {} + } + } + }, + "POST_/mentoring/v1/feedback/submit/{SessionId}": {} +} diff --git a/src/integration-tests-new/form/form.specs.js b/src/integration-tests-new/form/form.specs.js new file mode 100644 index 000000000..68b5b9231 --- /dev/null +++ b/src/integration-tests-new/form/form.specs.js @@ -0,0 +1,172 @@ +jest.setTimeout(30000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') + +const schemas = require('./schemas/form.schemas.json') + +let adminDetails = null +beforeAll(async () => { + adminDetails = await commonHelper.adminLogin() +}) + +describe('form endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/form/create', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/form/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req + .send({ + type: `session_${Date.now()}`, + sub_type: `createSessions_${Date.now()}`, + data: { + template_name: 'defaultTemplate', + fields: { + controls: [ + { + name: 'title', + label: 'title', + value: '', + class: 'ion-margin', + type: 'text', + position: 'floating', + validators: { + required: true, + min_length: 5, + }, + }, + { + name: 'categories', + label: 'Select categories', + value: '', + class: 'ion-margin', + type: 'chip', + position: '', + disabled: false, + show_select_all: true, + validators: { + required: true, + }, + }, + { + name: 'ages', + label: 'Select age', + value: '', + class: 'ion-margin', + type: 'chip', + position: '', + disabled: false, + show_select_all: true, + validators: { + required: true, + }, + }, + ], + }, + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + expect(res.body).toMatchSchema(schemas['POST_/mentoring/v1/form/create']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/form/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('PUT /mentoring/v1/form/update/{formId}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/form/update/1` + let req = request(BASE).put(url) + req = req.set('x-auth-token', adminDetails.token) + req = req + .send({ + type: 'session', + sub_type: 'createSessionsNew', + data: { + template_name: 'Test', + fields: { + controls: [ + { + name: 'title', + label: 'title', + value: '', + class: 'ion-margin', + type: 'text', + position: 'floating', + validators: { + required: true, + min_length: 5, + }, + }, + { + name: 'categories', + label: 'Select categories', + value: '', + class: 'ion-margin', + type: 'chip', + position: '', + disabled: false, + show_select_all: true, + validators: { + required: true, + }, + }, + { + name: 'ages', + label: 'Select age', + value: '', + class: 'ion-margin', + type: 'chip', + position: '', + disabled: false, + show_select_all: true, + validators: { + required: true, + }, + }, + ], + }, + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + expect(res.body).toMatchSchema(schemas['PUT_/mentoring/v1/form/update/{formId}']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/form/update/1` + const res = await request(BASE).put(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/form/read/{formId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/form/read/1` + let req = request(BASE).post(url) + req = req.set('x-auth-token', adminDetails.token) + req = req + .send({ + type: 'session', + sub_type: 'createSessionsNew', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['POST_/mentoring/v1/form/read/{formId}']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/form/read/1` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/form/schemas/form.schemas.json b/src/integration-tests-new/form/schemas/form.schemas.json new file mode 100644 index 000000000..96239b904 --- /dev/null +++ b/src/integration-tests-new/form/schemas/form.schemas.json @@ -0,0 +1,310 @@ +{ + "POST_/mentoring/v1/form/create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "version": { + "type": "number" + }, + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "sub_type": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "template_name": { + "type": "string" + }, + "fields": { + "type": "object", + "properties": { + "controls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "class": { + "type": "string" + }, + "type": { + "type": "string" + }, + "position": { + "type": "string" + }, + "validators": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + }, + "min_length": { + "type": "number" + } + } + }, + "disabled": { + "type": "boolean" + }, + "show_select_all": { + "type": "boolean" + } + }, + "required": [ + "name", + "label", + "value", + "class", + "type", + "position", + "validators" + ] + } + } + } + } + } + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "organization_id": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "version": { + "type": "number" + }, + "type": { + "type": "string" + } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "PUT_/mentoring/v1/form/update/{formId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + } + } + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "POST_/mentoring/v1/form/read/{formId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "version": { + "type": "number" + }, + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "sub_type": { + "type": "string" + }, + "data": { + "type": "object", + "properties": { + "template_name": { + "type": "string" + }, + "fields": { + "type": "object", + "properties": { + "controls": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "class": { + "type": "string" + }, + "type": { + "type": "string" + }, + "position": { + "type": "string" + }, + "validators": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + }, + "min_length": { + "type": "number" + } + } + }, + "disabled": { + "type": "boolean" + }, + "show_select_all": { + "type": "boolean" + } + }, + "required": [ + "name", + "label", + "value", + "class", + "type", + "position", + "validators" + ] + } + } + } + } + } + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "organization_id": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "version": { + "type": "number" + }, + "type": { + "type": "string" + } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/issues/issues.spec.js b/src/integration-tests-new/issues/issues.spec.js new file mode 100644 index 000000000..4e4b41e11 --- /dev/null +++ b/src/integration-tests-new/issues/issues.spec.js @@ -0,0 +1,28 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/issues.schemas.json') + +describe('issues endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/issues/create', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/issues/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + descriptaion: 'string', + meta_data: { + request_type: 'string', + browserName: 'string', + browserVersion: 'string', + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_issues_create'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/issues/schemas/issues.schemas.json b/src/integration-tests-new/issues/schemas/issues.schemas.json new file mode 100644 index 000000000..2efb7f085 --- /dev/null +++ b/src/integration-tests-new/issues/schemas/issues.schemas.json @@ -0,0 +1,37 @@ +{ + "POST_mentoring_v1_issues_create": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/mentees/mentees.specs.js b/src/integration-tests-new/mentees/mentees.specs.js new file mode 100644 index 000000000..76eca77fe --- /dev/null +++ b/src/integration-tests-new/mentees/mentees.specs.js @@ -0,0 +1,119 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +const schemas = require('./schemas/mentees.schemas.json') +let userDetails = null + +beforeAll(async () => { + console.log('setting up global variables....') + adminDetails = await commonHelper.adminLogin() + let adminToken = adminDetails.token + userDetails = await commonHelper.logIn() + + let profileCreate = await request(BASE) + .post('/mentoring/v1/profile/create') + .set('x-auth-token', userDetails.token) + .send({ + designation: ['beo', 'deo', 'testt'], + area_of_expertise: ['educational_leadership', 'sqaa'], + education_qualification: 'MBA', + tags: ['Experienced', 'Technical'], + visibility: 'visible', + organisation_ids: [1], + external_session_visibility: 'CURRENT', + external_mentor_visibility: 'ALL', + }) + + await request(BASE).post('/mentoring/v1/admin/triggerViewRebuild').set('x-auth-token', adminToken) +}) + +describe('mentees endpoints generated from api-doc.yaml', () => { + // describe('GET /mentoring/v1/mentees/sessions', () => { + // test('should return 200', async () => { + // const url = `/mentoring/v1/mentees/sessions?page=1&limit=2`; + // let req = request(BASE).get(url); + // req = req.set('x-auth-token', "string"); + // const res = await req; + // expect(res.status).toBe(200); + // expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentees/sessions']); + // }); + + // test('should return 401/403 when unauthorized', async () => { + // const url = `/mentoring/v1/mentees/sessions?page=1&limit=2`; + // const res = await request(BASE).get(url); + // expect([401,403]).toContain(res.status); + // }); + + // }); + + // describe('GET /mentoring/v1/mentees/joinSession/{sessionId}', () => { + // test('should return 200', async () => { + // const url = `/mentoring/v1/mentees/joinSession/62832531a05cbd57b273aebb`; + // let req = request(BASE).get(url); + // req = req.set('x-auth-token', "string"); + // const res = await req; + // expect(res.status).toBe(200); + // expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentees/joinSession/{sessionId}']); + // }); + + // test('should return 401/403 when unauthorized', async () => { + // const url = `/mentoring/v1/mentees/joinSession/62832531a05cbd57b273aebb`; + // const res = await request(BASE).get(url); + // expect([401,403]).toContain(res.status); + // }); + + // }); + + // describe('GET /mentoring/v1/mentees/reports', () => { + // test('should return 200', async () => { + // const url = `/mentoring/v1/mentees/reports?filterType=QUARTERLY`; + // let req = request(BASE).get(url); + // req = req.set('x-auth-token', "string"); + // const res = await req; + // expect(res.status).toBe(200); + // expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentees/reports']); + // }); + + // test('should return 401/403 when unauthorized', async () => { + // const url = `/mentoring/v1/mentees/reports?filterType=QUARTERLY`; + // const res = await request(BASE).get(url); + // expect([401,403]).toContain(res.status); + // }); + + // }); + + describe('GET /mentoring/v1/mentees/homeFeed', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentees/homeFeed` + let req = request(BASE).get(url) + req = req.set('x-auth-token', userDetails.token) + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentees/homeFeed']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentees/homeFeed` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/mentees/list', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentees/list?page=1&limit=5&search=&connected_mentees=true&mentorId=${userDetails.id}` + let req = request(BASE).get(url) + req = req.set('x-auth-token', userDetails.token) + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentees/list']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentees/list?page=1&limit=5&search=&connected_mentees=true&mentorId=${userDetails.id}` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/mentees/schemas/mentees.schemas.json b/src/integration-tests-new/mentees/schemas/mentees.schemas.json new file mode 100644 index 000000000..ad4075c89 --- /dev/null +++ b/src/integration-tests-new/mentees/schemas/mentees.schemas.json @@ -0,0 +1,247 @@ +{ + "GET_/mentoring/v1/mentees/sessions": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "user_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "meeting_info": { + "type": "object", + "properties": { + "platform": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "created_at": { + "type": "string" + }, + "is_enrolled": { + "type": "boolean" + }, + "mentor_name": { + "type": "string" + }, + "organization_id": { + "type": "string" + } + }, + "required": [ + "id", + "title", + "description", + "image", + "user_id", + "status", + "start_date", + "end_date", + "meeting_info", + "created_at", + "is_enrolled", + "mentor_name", + "organization_id" + ] + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentees/joinSession/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "link": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentees/reports": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "total_session_enrolled": { + "type": "number" + }, + "total_sessions_attended": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": {} + } + } + }, + "GET_/mentoring/v1/mentees/homeFeed": { + "type": "object", + "properties": { + "responseCode": { "type": "string" }, + "message": { "type": "string" }, + "result": { + "type": "object", + "properties": { + "my_sessions": { + "type": "array" + }, + "my_sessions_count": { + "type": ["number", "integer"] + } + } + }, + "meta": { + "type": "object", + "properties": { + "type": { "type": "string" }, + "data": { "type": "array" }, + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { "type": "string" }, + "meetingPlatform": { "type": "string" } + }, + "required": ["type", "data", "correlation", "meetingPlatform"] + } + }, + "required": ["responseCode", "message", "result", "meta"], + "additionalProperties": true + }, + "GET_/mentoring/v1/mentees/list": { + "type": "object", + + "properties": { + "message": { "type": "string" }, + + "result": { + "type": "object", + "properties": { + "data": { + "type": "array" + }, + "count": { + "type": ["number", "integer"] + } + }, + "required": ["data", "count"], + "additionalProperties": true + }, + + "meta": {} + }, + + "required": ["message", "result"], + + "additionalProperties": true + } +} diff --git a/src/integration-tests-new/mentoring/mentoring.spec.js b/src/integration-tests-new/mentoring/mentoring.spec.js new file mode 100644 index 000000000..c81d747c7 --- /dev/null +++ b/src/integration-tests-new/mentoring/mentoring.spec.js @@ -0,0 +1,17 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/mentoring.schemas.json') + +describe('mentoring endpoints generated from api-doc.yaml', () => { + describe('GET /mentoring/health', () => { + test('should return 200', async () => { + const url = `/mentoring/health` + let req = request(BASE).get(url) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_health'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/mentoring/schemas/mentoring.schemas.json b/src/integration-tests-new/mentoring/schemas/mentoring.schemas.json new file mode 100644 index 000000000..ac7ccaba4 --- /dev/null +++ b/src/integration-tests-new/mentoring/schemas/mentoring.schemas.json @@ -0,0 +1,71 @@ +{ + "GET_mentoring_health": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "ver": { + "type": "string" + }, + "ts": { + "type": "string" + }, + "params": { + "type": "object", + "properties": { + "resmsgid": { + "type": "string" + }, + "msgid": { + "type": "string" + }, + "status": { + "type": "string" + }, + "err": { + "type": "null" + }, + "errMsg": { + "type": "null" + } + } + }, + "status": { + "type": "number" + }, + "result": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "healthy": { + "type": "boolean" + }, + "checks": { + "type": "array", + "items": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "healthy": { + "type": "boolean" + }, + "err": { + "type": "string" + }, + "errMsg": { + "type": "string" + } + }, + "required": ["name", "healthy", "err", "errMsg"] + } + } + } + } + } + } +} diff --git a/src/integration-tests-new/mentors/mentors.specs.js b/src/integration-tests-new/mentors/mentors.specs.js new file mode 100644 index 000000000..371e0dfc6 --- /dev/null +++ b/src/integration-tests-new/mentors/mentors.specs.js @@ -0,0 +1,142 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +let userDetails = null +const schemas = require('./schemas/mentors.schemas.json') + +beforeAll(async () => { + console.log('setting up global variables....') + userDetails = await commonHelper.mentorLogIn() + + /* + let profileCreate = await request(BASE).post('/mentoring/v1/profile/create').set('x-auth-token', userDetails.token).send({ + designation: ['beo', 'deo', 'testt'], + area_of_expertise: ['educational_leadership', 'sqaa'], + education_qualification: 'MBA', + tags: ['Experienced', 'Technical'], + visibility: 'visible', + organisation_ids: [1], + external_session_visibility: 'CURRENT', + external_mentor_visibility: 'ALL', + }) + + console.log(profileCreate.body, 'profileCreatebody') + */ +}) + +describe('mentors endpoints generated from api-doc.yaml', () => { + /* + describe('GET /mentoring/v1/mentors/details/{mentorId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/details/62a820225ff93f30cfe5f990`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "string"); + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/details/{mentorId}']) + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/details/62a820225ff93f30cfe5f990`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('GET /mentoring/v1/mentors/reports', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/reports?filterType=QUARTERLY`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "string"); + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/reports']) + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/reports?filterType=QUARTERLY`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('GET /mentoring/v1/mentors/upcomingSessions/{mentorId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/upcomingSessions/62a820225ff93f30cfe5f990?page=1&limit=2&search=jhon`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "string"); + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/upcomingSessions/{mentorId}']) + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/upcomingSessions/62a820225ff93f30cfe5f990?page=1&limit=2&search=jhon`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('GET /mentoring/v1/mentors/share/{mentorId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/share/21`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "string"); + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/share/{mentorId}']) + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/share/21`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + */ + + describe('GET /mentoring/v1/mentors/list', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/list?page=1&limit=10&search=&directory=true&search_on=` + let req = request(BASE).get(url) + req = req.set('x-auth-token', userDetails.token) + const res = await req + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/list']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/list?page=1&limit=100&search=&directory=true&search_on=` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/mentors/createdSessions', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/mentors/createdSessions?page=1&limit=100&search=` + let req = request(BASE).get(url) + req = req.set('x-auth-token', userDetails.token) + const res = await req + + expect(res.status).toBe(200) + expect(res.body).toMatchSchema(schemas['GET_/mentoring/v1/mentors/createdSessions']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/mentors/createdSessions?page=1&limit=100&search=` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/mentors/schemas/mentors.schemas.json b/src/integration-tests-new/mentors/schemas/mentors.schemas.json new file mode 100644 index 000000000..9ac8e46b3 --- /dev/null +++ b/src/integration-tests-new/mentors/schemas/mentors.schemas.json @@ -0,0 +1,381 @@ +{ + "GET_/mentoring/v1/mentors/details/{mentorId}": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "sessions_attended": { + "type": "number" + }, + "sessions_hosted": { + "type": "number" + }, + "id": { + "type": "number" + }, + "email": { + "type": "string" + }, + "verified": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "terms_and_conditions": { + "type": "boolean" + }, + "designation": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "location": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "languages": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "last_logged_in_at": { + "type": "string" + }, + "about": { + "type": "string" + }, + "experience": { + "type": "string" + }, + "user_roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "user_type": { + "type": "number" + }, + "status": { + "type": "string" + } + } + } + }, + "image": { + "type": "string" + }, + "rating": { + "type": "object", + "properties": { + "average": { + "type": "number" + }, + "votes": { + "type": "number" + }, + "breakup": { + "type": "array", + "items": { + "type": "object", + "properties": { + "star": { + "type": "number" + }, + "votes": { + "type": "number" + } + }, + "required": ["star", "votes"] + } + } + } + }, + "preferred_language": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentors/reports": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "total_session_created": { + "type": "number" + }, + "total_session_hosted": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentors/upcomingSessions/{mentorId}": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "user_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "meeting_info": { + "type": "object", + "properties": { + "platform": { + "type": "string" + } + } + }, + "mentor_name": { + "type": "string" + }, + "organization_id": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentors/share/{mentorId}": { + "type": "object", + "properties": { + "response_code": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "share_link": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/mentors/list": { + "type": "object", + "properties": { + "message": { "type": "string" }, + + "result": { + "type": "object", + "properties": { + "data": { + "type": "array" + }, + "count": { + "type": ["number", "integer"] + } + }, + "required": ["data", "count"], + "additionalProperties": true + }, + + "meta": {} + }, + + "required": ["message", "result"], + + "additionalProperties": true + }, + "GET_/mentoring/v1/mentors/createdSessions": { + "type": "object", + + "properties": { + "message": { "type": "string" }, + + "result": { + "oneOf": [ + { + "type": "object", + "properties": { + "count": { "type": ["number", "integer"] }, + "data": { "type": "array" } + }, + "required": ["count", "data"], + "additionalProperties": true + }, + { + "type": "array" + } + ] + }, + + "meta": {} + }, + + "required": ["message", "result"], + + "additionalProperties": true + } +} diff --git a/src/integration-tests-new/modules/modules.spec.js b/src/integration-tests-new/modules/modules.spec.js new file mode 100644 index 000000000..7b1bc18f6 --- /dev/null +++ b/src/integration-tests-new/modules/modules.spec.js @@ -0,0 +1,85 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/modules.schemas.json') + +describe('modules endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/modules/create', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/modules/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + code: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_modules_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/modules/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/modules/update/{id}', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/modules/update/{id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + code: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_modules_update_id'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/modules/update/{id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('DELETE /mentoring/v1/modules/delete/{id}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/modules/delete/{id}` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_modules_delete_id'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/modules/list?page={page}&limit={limit}&search={search}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/modules/list?page=1&limit=2&search=John` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_modules_list_page_page_limit_limit_search_search'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/modules/schemas/modules.schemas.json b/src/integration-tests-new/modules/schemas/modules.schemas.json new file mode 100644 index 000000000..3c2db8bc2 --- /dev/null +++ b/src/integration-tests-new/modules/schemas/modules.schemas.json @@ -0,0 +1,152 @@ +{ + "POST_mentoring_v1_modules_create": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "Id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_modules_update_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "status": { + "type": "string" + }, + "code": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_modules_delete_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": {} + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_modules_list_page_page_limit_limit_search_search": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "status": { + "type": "string" + } + }, + "required": ["id", "code", "status"] + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/org-admin/org-admin.spec.js b/src/integration-tests-new/org-admin/org-admin.spec.js new file mode 100644 index 000000000..9525f65ec --- /dev/null +++ b/src/integration-tests-new/org-admin/org-admin.spec.js @@ -0,0 +1,151 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/org-admin.schemas.json') + +describe('org-admin endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/org-admin/roleChange', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/org-admin/roleChange` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + user_id: 'string', + current_roles: ['string'], + new_roles: ['string'], + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_roleChange'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/org-admin/inheritEntityType', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/inheritEntityType` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + entity_type_value: 'string', + target_entity_type_label: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_inheritEntityType'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/org-admin/getOrgPolicies', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/getOrgPolicies` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_org-admin_getOrgPolicies'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/org-admin/updateRelatedOrgs', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/updateRelatedOrgs` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + responseCode: 'string', + message: 'string', + result: ['string'], + meta: { + correlation: 'string', + meetingPlatform: 'string', + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_updateRelatedOrgs'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/org-admin/setOrgPolicies', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/setOrgPolicies` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + session_visibility_policy: 'string', + mentor_visibility_policy: 'string', + external_session_visibility_policy: 'string', + external_mentor_visibility_policy: 'string', + allow_mentor_override: true, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_setOrgPolicies'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/org-admin/uploadSampleCSV', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/uploadSampleCSV` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req.send('string').set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_uploadSampleCSV'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/org-admin/updateTheme', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/updateTheme` + let req = request(BASE).post(url) + req = req.set('X-auth-token', 'bearer {{token}}') + req = req + .send({ + primaryColor: '#E74C3C', + secondaryColor: '#F1C40F', + backgroundColor: '#FFFFFF', + textColor: '#34495E', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_org-admin_updateTheme'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/org-admin/themeDetails', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/org-admin/themeDetails` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_org-admin_themeDetails'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/org-admin/schemas/org-admin.schemas.json b/src/integration-tests-new/org-admin/schemas/org-admin.schemas.json new file mode 100644 index 000000000..d87b9eb6b --- /dev/null +++ b/src/integration-tests-new/org-admin/schemas/org-admin.schemas.json @@ -0,0 +1,396 @@ +{ + "POST_mentoring_v1_org-admin_roleChange": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "user_id": { + "type": "string" + }, + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_org-admin_inheritEntityType": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "allow_filtering": { + "type": "boolean" + }, + "data_type": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "parent_id": { + "type": "number" + }, + "allow_custom_entities": { + "type": "boolean" + }, + "has_entities": { + "type": "boolean" + }, + "model_names": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_org-admin_getOrgPolicies": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "session_visibility_policy": { + "type": "string" + }, + "mentor_visibility_policy": { + "type": "string" + }, + "external_session_visibility_policy": { + "type": "string" + }, + "external_mentor_visibility_policy": { + "type": "string" + }, + "approval_required_for": { + "type": "array", + "items": { + "type": "string" + } + }, + "allow_mentor_override": { + "type": "boolean" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_org-admin_updateRelatedOrgs": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "organization_id": { + "type": "string" + }, + "session_visibility_policy": { + "type": "string" + }, + "mentor_visibility_policy": { + "type": "string" + }, + "external_session_visibility_policy": { + "type": "string" + }, + "external_mentor_visibility_policy": { + "type": "string" + }, + "approval_required_for": { + "type": "array", + "items": { + "type": "string" + } + }, + "allow_mentor_override": { + "type": "boolean" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_org-admin_setOrgPolicies": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "session_visibility_policy": { + "type": "string" + }, + "mentor_visibility_policy": { + "type": "string" + }, + "external_session_visibility_policy": { + "type": "string" + }, + "external_mentor_visibility_policy": { + "type": "string" + }, + "allow_mentor_override": { + "type": "boolean" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "approval_required_for": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_org-admin_uploadSampleCSV": { + "responseCode": "OK", + "message": "CSV_UPLOADED_SUCCESSFULLY", + "result": [], + "meta": { + "formsVersion": [ + { + "id": 3, + "type": "termsAndConditions", + "version": 0 + }, + { + "id": 4, + "type": "faq", + "version": 0 + }, + { + "id": 5, + "type": "helpVideos", + "version": 0 + }, + { + "id": 6, + "type": "platformApp", + "version": 4 + }, + { + "id": 1, + "type": "editProfile", + "version": 0 + }, + { + "id": 2, + "type": "session", + "version": 0 + }, + { + "id": 8, + "type": "sampleCsvDownload", + "version": 0 + }, + { + "id": 7, + "type": "helpApp", + "version": 0 + }, + { + "id": 9, + "type": "mentorQuestionnaire", + "version": 0 + }, + { + "id": 10, + "type": "managersSession", + "version": 0 + } + ], + "correlation": "8d1d9ec0-68c4-4def-9dad-2cac06ed71a2", + "meetingPlatform": "BBB" + }, + "type": "string" + }, + "POST_mentoring_v1_org-admin_updateTheme": { + "type": "string" + }, + "GET_mentoring_v1_org-admin_themeDetails": { + "type": "string" + } +} diff --git a/src/integration-tests-new/permissions/permissions.spec.js b/src/integration-tests-new/permissions/permissions.spec.js new file mode 100644 index 000000000..1819280a3 --- /dev/null +++ b/src/integration-tests-new/permissions/permissions.spec.js @@ -0,0 +1,84 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/permissions.schemas.json') + +describe('permissions endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/permissions/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/permissions/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + code: 'string', + module: 'string', + request_type: ['string'], + api_path: 'string', + status: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_permissions_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/permissions/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/permissions/update/{id}', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/permissions/update/{id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + code: 'string', + module: 'string', + request_type: ['string'], + api_path: 'string', + status: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_permissions_update_id'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/permissions/delete/{id}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/permissions/delete/{id}` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_permissions_delete_id'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/permissions/list?page={page}&limit={limit}&search={search}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/permissions/list?page=1&limit=2&search=John` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_permissions_list_page_page_limit_limit_search_search'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/permissions/schemas/permissions.schemas.json b/src/integration-tests-new/permissions/schemas/permissions.schemas.json new file mode 100644 index 000000000..06635c97a --- /dev/null +++ b/src/integration-tests-new/permissions/schemas/permissions.schemas.json @@ -0,0 +1,180 @@ +{ + "POST_mentoring_v1_permissions_create": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "Id": { + "type": "number" + }, + "status": { + "type": "string" + }, + "module": { + "type": "string" + }, + "request_type": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_permissions_update_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "Id": { + "type": "number" + }, + "status": { + "type": "string" + }, + "module": { + "type": "string" + }, + "request_type": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_permissions_delete_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": {} + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_permissions_list_page_page_limit_limit_search_search": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "results": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "module": { + "type": "string" + }, + "request_type": { + "type": "array", + "items": { + "type": "string" + } + }, + "api_path": { + "type": "string" + }, + "status": { + "type": "string" + } + } + } + }, + "count": { + "type": "number" + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/profile/profile.specs.js b/src/integration-tests-new/profile/profile.specs.js new file mode 100644 index 000000000..58e685fec --- /dev/null +++ b/src/integration-tests-new/profile/profile.specs.js @@ -0,0 +1,61 @@ +jest.setTimeout(100000) +const request = require('supertest') +const fs = require('fs') +const path = require('path') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +let mentorDetails = null +const schemas = require('./schemas/profile.schemas.json') + +beforeAll(async () => { + mentorDetails = await commonHelper.logIn() +}) + +describe('profile endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/profile/update', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/profile/update` + let req = request(BASE).post(url) + req = req.set('x-auth-token', mentorDetails.token) + req = req + .send({ + designation: ['Principal'], + area_of_expertise: ['educational_leadership'], + experience: '5', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_profile_update'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/profile/filterList?entity_types={entity_types}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/profile/filterList?entity_types=designation` + let req = request(BASE).get(url) + req = req.set('x-auth-token', mentorDetails.token) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_profile_filterList_entity_types_entity_types'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/profile/details', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/profile/details/${mentorDetails.userId}` + let req = request(BASE).get(url) + req = req.set('x-auth-token', mentorDetails.token) + const res = await req + expect(res.status).toBe(200) + + // validate response schema + const schema = schemas['GET_mentoring_v1_profile_details'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/profile/schemas/profile.schemas.json b/src/integration-tests-new/profile/schemas/profile.schemas.json new file mode 100644 index 000000000..0294890e8 --- /dev/null +++ b/src/integration-tests-new/profile/schemas/profile.schemas.json @@ -0,0 +1,458 @@ +{ + "POST_mentoring_v1_profile_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "designation": { + "type": "string" + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "rating": { + "type": "object", + "properties": { + "average": { + "type": "number" + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "age": { + "type": "number" + }, + "experience": { + "type": "string" + } + } + }, + "stats": { + "type": "object", + "properties": { + "sessions_attended": { + "type": "number" + }, + "students_mentored": { + "type": "number" + } + } + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "configs": { + "type": "object", + "properties": { + "notification": { + "type": "boolean" + }, + "visibility": { + "type": "string" + } + } + }, + "visibility": { + "type": "string" + }, + "organisation_ids": { + "type": "array", + "items": { + "type": "number" + } + }, + "external_session_visibility": { + "type": "string" + }, + "external_mentor_visibility": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "user_roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "user_type": { + "type": "number" + }, + "status": { + "type": "string" + } + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_profile_update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "user_id": { + "type": "string" + }, + "designation": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { "type": "string" }, + "label": { "type": "string" } + } + } + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { "type": "string" }, + "label": { "type": "string" } + } + } + }, + "education_qualification": { "type": "null" }, + "rating": { "type": "null" }, + "meta": { "type": "null" }, + "stats": { "type": "null" }, + "tags": { "type": "null" }, + "configs": { "type": "null" }, + "visible_to_organizations": { + "type": "array", + "items": { "type": "string" } + }, + "external_session_visibility": { "type": "string" }, + "experience": { "type": "string" }, + "organization_id": { "type": "string" }, + "external_mentee_visibility": { "type": "string" }, + "mentee_visibility": { "type": "string" }, + "external_mentor_visibility": { "type": "string" }, + "mentor_visibility": { "type": "string" }, + "name": { "type": "string" }, + "email": { "type": "string" }, + "phone": { "type": "null" }, + "is_mentor": { "type": "boolean" }, + "settings": { + "type": "object", + "properties": { + "chat_enabled": { "type": "boolean" } + } + }, + "image": { "type": "string" }, + "gender": { "type": "null" }, + "status": { "type": "string" }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_profile_filterList_entity_types_entity_types": {}, + "GET_mentoring_v1_profile_details": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "user_id": { + "type": "string" + }, + "designation": { + "type": ["array", "null"], + "items": { + "type": "object", + "properties": { + "value": { "type": "string" }, + "label": { "type": "string" } + } + } + }, + "area_of_expertise": { + "type": ["array", "null"], + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { "type": ["null", "string", "array"] }, + "rating": { "type": ["null", "object"] }, + "meta": { "type": ["null", "object"] }, + "stats": { "type": ["null", "object"] }, + "tags": { "type": ["null", "array"] }, + "configs": { "type": ["null", "object"] }, + "external_session_visibility": { + "type": "string" + }, + "experience": { + "type": ["null", "string"] + }, + "organization_id": { + "type": "string" + }, + "external_mentee_visibility": { + "type": "string" + }, + "mentee_visibility": { + "type": "string" + }, + "external_mentor_visibility": { + "type": "string" + }, + "mentor_visibility": { + "type": "string" + }, + "name": { + "type": "string" + }, + "is_mentor": { + "type": "boolean" + }, + "settings": { + "type": "object", + "properties": { + "chat_enabled": { "type": "boolean" } + } + }, + "image": { "type": "string" }, + "gender": { + "type": "null" + }, + "status": { + "type": "string" + }, + "organization_code": { + "type": "string" + }, + "tenant_code": { + "type": "string" + }, + "user_name": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "profile_mandatory_fields": { + "type": "array", + "items": { + "type": "string" + } + }, + "organization": { + "type": "object", + "properties": { + "id": { "type": "string" }, + "name": { "type": ["null", "string"] } + } + }, + "sessions_attended": { + "type": "number" + }, + "sessions_hosted": { + "type": "number" + }, + "is_connected": { + "type": "boolean" + }, + "visible_to_organizations": { + "type": "array", + "items": { "type": "string" } + }, + "displayProperties": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { "type": "string" }, + "label": { "type": "string" }, + "visible": { "type": "boolean" }, + "visibility": { "type": "string" }, + "sequence": { "type": "number" } + }, + "required": ["key"] + } + }, + "Permissions": { + "type": "array", + "items": { + "type": "object", + "properties": { + "module": { "type": "string" }, + "request_type": { + "type": "array", + "items": { "type": "string" } + }, + "service": { "type": "string" } + }, + "required": ["module", "request_type", "service"] + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/question-set/question-set.spec.js b/src/integration-tests-new/question-set/question-set.spec.js new file mode 100644 index 000000000..4f2606b45 --- /dev/null +++ b/src/integration-tests-new/question-set/question-set.spec.js @@ -0,0 +1,74 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/question-set.schemas.json') + +describe('question-set endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/question-set/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/question-set/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + questions: [1], + code: 'feedback', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_/mentoring/v1/question-set/create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/question-set/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('PATCH /mentoring/v1/question-set/update/{QuestionSetId}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/question-set/update/1` + let req = request(BASE).patch(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + questions: [1], + code: 'UpdatedFeedbackCode', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['PATCH_/mentoring/v1/question-set/update/{QuestionSetId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/question-set/update/1` + const res = await request(BASE).patch(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/question-set/read/{QuestionSetId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/question-set/read/1` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_/mentoring/v1/question-set/read/{QuestionSetId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/question-set/read/1` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/question-set/schemas/question-set.schemas.json b/src/integration-tests-new/question-set/schemas/question-set.schemas.json new file mode 100644 index 000000000..d60b9afe5 --- /dev/null +++ b/src/integration-tests-new/question-set/schemas/question-set.schemas.json @@ -0,0 +1,176 @@ +{ + "POST_/mentoring/v1/question-set/create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "id": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "type": "string" + } + }, + "code": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "meta": { + "type": "null" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "PATCH_/mentoring/v1/question-set/update/{QuestionSetId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "status": { + "type": "string" + }, + "id": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "type": "string" + } + }, + "code": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "meta": { + "type": "null" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "POST_/mentoring/v1/question-set/read/{QuestionSetId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "questions": { + "type": "array", + "items": { + "type": "string" + } + }, + "code": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/questions/questions.spec.js b/src/integration-tests-new/questions/questions.spec.js new file mode 100644 index 000000000..42bd588a8 --- /dev/null +++ b/src/integration-tests-new/questions/questions.spec.js @@ -0,0 +1,102 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/questions.schemas.json') + +describe('questions endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/questions/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/questions/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + name: 'keyvalue', + question: 'To what extent did you feel comfortable sharing your thoughts in the session?', + type: 'rating', + options: null, + no_of_stars: 5, + status: 'active', + category: null, + rendering_data: { + value: '', + class: 'ion-margin', + disabled: false, + noOfstars: '5', + position: 'floating', + validation: { + required: false, + }, + }, + meta: null, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_/mentoring/v1/questions/create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/questions/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('PUT /mentoring/v1/questions/update/{QuestionId}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/questions/update/1` + let req = request(BASE).put(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + name: 'keyvalue', + question: 'To what extent were you able to learn new skills in the session Org?', + type: 'rating', + options: null, + no_of_stars: 5, + status: 'active', + category: { + evaluating: 'mentor', + }, + rendering_data: { + validators: { + required: true, + }, + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['PUT_/mentoring/v1/questions/update/{QuestionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/questions/update/1` + const res = await request(BASE).put(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/questions/read/{QuestionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/questions/read/1` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_/mentoring/v1/questions/read/{QuestionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/questions/read/1` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/questions/schemas/questions.schemas.json b/src/integration-tests-new/questions/schemas/questions.schemas.json new file mode 100644 index 000000000..18ea61450 --- /dev/null +++ b/src/integration-tests-new/questions/schemas/questions.schemas.json @@ -0,0 +1,293 @@ +{ + "POST_/mentoring/v1/questions/create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "question": { + "type": "string" + }, + "type": { + "type": "string" + }, + "options": { + "type": "null" + }, + "no_of_stars": { + "type": "number" + }, + "status": { + "type": "string" + }, + "category": { + "type": "null" + }, + "rendering_data": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "class": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "noOfstars": { + "type": "string" + }, + "position": { + "type": "string" + }, + "validation": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + } + } + } + } + }, + "meta": { + "type": "null" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "PUT_/mentoring/v1/questions/update/{QuestionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "question": { + "type": "string" + }, + "type": { + "type": "string" + }, + "options": { + "type": "null" + }, + "no_of_stars": { + "type": "number" + }, + "status": { + "type": "string" + }, + "category": { + "type": "null" + }, + "rendering_data": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "class": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "noOfstars": { + "type": "string" + }, + "position": { + "type": "string" + }, + "validation": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + } + } + } + } + }, + "meta": { + "type": "null" + }, + "updated_at": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/questions/read/{QuestionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "question": { + "type": "string" + }, + "options": { + "type": "null" + }, + "type": { + "type": "string" + }, + "no_of_stars": { + "type": "number" + }, + "status": { + "type": "string" + }, + "category": { + "type": "null" + }, + "rendering_data": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "class": { + "type": "string" + }, + "disabled": { + "type": "boolean" + }, + "noOfstars": { + "type": "string" + }, + "position": { + "type": "string" + }, + "validation": { + "type": "object", + "properties": { + "required": { + "type": "boolean" + } + } + } + } + }, + "meta": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "string" + } + }, + "correlation": { + "type": "string" + }, + "meeting_platform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/report-mapping/report-mapping.spec.js b/src/integration-tests-new/report-mapping/report-mapping.spec.js new file mode 100644 index 000000000..c6f85776c --- /dev/null +++ b/src/integration-tests-new/report-mapping/report-mapping.spec.js @@ -0,0 +1,78 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/report-mapping.schemas.json') + +describe('report-mapping endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/report-mapping/create', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-mapping/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + report_code: 'string', + role_title: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-mapping_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/report-mapping/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/report-mapping/read', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-mapping/read?code=total_number_of_sessions_attended` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_report-mapping_read'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/report-mapping/update', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-mapping/update?id=16` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + report_code: 'string', + role_title: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-mapping_update'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/report-mapping/delete', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-mapping/delete?id=16` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_report-mapping_delete'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/report-mapping/schemas/report-mapping.schemas.json b/src/integration-tests-new/report-mapping/schemas/report-mapping.schemas.json new file mode 100644 index 000000000..1cf422852 --- /dev/null +++ b/src/integration-tests-new/report-mapping/schemas/report-mapping.schemas.json @@ -0,0 +1,237 @@ +{ + "POST_mentoring_v1_report-mapping_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "report_code": { + "type": "string" + }, + "role_title": { + "type": "string" + }, + "id": { + "type": "number" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_report-mapping_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "report_code": { + "type": "string" + }, + "role_title": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_report-mapping_update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "report_code": { + "type": "string" + }, + "role_title": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_report-mapping_delete": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/report-queries/report-queries.spec.js b/src/integration-tests-new/report-queries/report-queries.spec.js new file mode 100644 index 000000000..47ac4b8aa --- /dev/null +++ b/src/integration-tests-new/report-queries/report-queries.spec.js @@ -0,0 +1,66 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/report-queries.schemas.json') + +describe('report-queries endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/report-queries/create', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-queries/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-queries_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/report-queries/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/report-queries/read', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-queries/read?code=string` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_report-queries_read'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/report-queries/update', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/report-queries/update?code=string` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-queries_update'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/report-queries/delete', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-queries/delete?id=1` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_report-queries_delete'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/report-queries/schemas/report-queries.schemas.json b/src/integration-tests-new/report-queries/schemas/report-queries.schemas.json new file mode 100644 index 000000000..8af5a847a --- /dev/null +++ b/src/integration-tests-new/report-queries/schemas/report-queries.schemas.json @@ -0,0 +1,246 @@ +{ + "POST_mentoring_v1_report-queries_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "status": { + "type": "string" + }, + "report_code": { + "type": "string" + }, + "query": { + "type": "string" + }, + "id": { + "type": "number" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_report-queries_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "report_code": { + "type": "string" + }, + "query": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_report-queries_update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "report_code": { + "type": "string" + }, + "query": { + "type": "string" + }, + "status": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_report-queries_delete": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/report-type/report-type.spec.js b/src/integration-tests-new/report-type/report-type.spec.js new file mode 100644 index 000000000..2e352cbc1 --- /dev/null +++ b/src/integration-tests-new/report-type/report-type.spec.js @@ -0,0 +1,76 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/report-type.schemas.json') + +describe('report-type endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/report-type/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/report-type/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + title: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-type_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/report-type/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/report-type/read', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-type/read?title=random_title` + let req = request(BASE).get(url) + req = req.set('x-auth-token', TOKEN) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_report-type_read'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/report-type/update', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-type/update?id=1` + let req = request(BASE).post(url) + req = req.set('x-auth-token', TOKEN) + req = req + .send({ + title: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['POST_mentoring_v1_report-type_update'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/report-type/delete', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/report-type/delete?id=1` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_report-type_delete'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/report-type/schemas/report-type.schemas.json b/src/integration-tests-new/report-type/schemas/report-type.schemas.json new file mode 100644 index 000000000..a274988d3 --- /dev/null +++ b/src/integration-tests-new/report-type/schemas/report-type.schemas.json @@ -0,0 +1,228 @@ +{ + "POST_mentoring_v1_report-type_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "title": { + "type": "string" + }, + "id": { + "type": "number" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_report-type_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_report-type_update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_report-type_delete": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/reports/reports.spec.js b/src/integration-tests-new/reports/reports.spec.js new file mode 100644 index 000000000..3673641cc --- /dev/null +++ b/src/integration-tests-new/reports/reports.spec.js @@ -0,0 +1,144 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/reports.schemas.json') + +describe('reports endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/reports/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/reports/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + code: 'string', + title: 'string', + description: 'string', + report_type_title: 'string', + created_at: 'string', + updated_at: 'string', + config: { + columns: [ + { + key: 'string', + label: 'string', + filter: true, + sort: true, + search: true, + filterType: 'string', + isEntityType: true, + isMultipleFilter: true, + dataType: 'string', + defaultValues: [ + { + label: 'string', + value: 'string', + }, + ], + }, + ], + }, + organization_id: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_reports_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/reports/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/reports/read', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/reports/read?id=1` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['GET_mentoring_v1_reports_read'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/reports/update/{id}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/reports/update/string` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + code: 'string', + title: 'string', + description: 'string', + report_type_title: 'string', + config: 'string', + organization_id: 1, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['POST_mentoring_v1_reports_update_id'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('DELETE /mentoring/v1/reports/delete', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/reports/delete?id=1` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_reports_delete'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/reports/reportData', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/reports/reportData?report_code=report_code&report_role=role&start_date=1735756200&end_date=1738348199&session_type=All&download_csv=string&pageNo=1&Limit=1&organization=string&group_by=string&entities_value=string&sort_column=string&sort_value=string` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + filters: { + mentor_name: ['string'], + }, + search: { + mentor_name: ['string'], + }, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_reports_reportData'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/reports/filterList', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/reports/filterList?filter_type=session&report_filter=true` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_reports_filterList'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integration-tests-new/reports/schemas/reports.schemas.json b/src/integration-tests-new/reports/schemas/reports.schemas.json new file mode 100644 index 000000000..7e7d7c57b --- /dev/null +++ b/src/integration-tests-new/reports/schemas/reports.schemas.json @@ -0,0 +1,838 @@ +{ + "POST_mentoring_v1_reports_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "report_type_title": { + "type": "string" + }, + "config": { + "type": "object", + "properties": { + "columns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "sort": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "filter": { + "type": "boolean" + }, + "search": { + "type": "boolean" + }, + "filterType": { + "type": "string" + }, + "isEntityType": { + "type": "boolean" + }, + "isMultipleFilter": { + "type": "boolean" + }, + "dataType": { + "type": "string" + }, + "defaultValues": { + "type": "array", + "items": { + "type": "object", + "properties": { + "label": { + "type": "string" + }, + "value": { + "type": "string" + } + }, + "required": ["label", "value"] + } + } + }, + "required": [ + "key", + "sort", + "label", + "filter", + "search", + "filterType", + "isEntityType", + "isMultipleFilter", + "defaultValues" + ] + } + } + } + }, + "organization_id": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_reports_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "report_type_title": { + "type": "string" + }, + "config": { + "type": "object", + "properties": {} + }, + "organization_id": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_reports_update_id": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "code": { + "type": "string" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "report_type_title": { + "type": "string" + }, + "config": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_reports_delete": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_reports_reportData": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "report_type": { + "type": "string" + }, + "config": { + "type": "object", + "properties": { + "columns": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "sort": { + "type": "boolean" + }, + "label": { + "type": "string" + }, + "filter": { + "type": "boolean" + }, + "search": { + "type": "boolean" + }, + "filterType": { + "type": "string" + }, + "isEntityType": { + "type": "boolean" + }, + "isMultipleFilter": { + "type": "boolean" + }, + "dataType": { + "type": "string" + }, + "defaultValues": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "key", + "sort", + "label", + "filter", + "search", + "filterType", + "isEntityType", + "isMultipleFilter", + "defaultValues" + ] + } + } + } + }, + "count": { + "type": "number" + }, + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "sessions_title": { + "type": "string" + }, + "sessions_created_by": { + "type": "string" + }, + "number_of_mentees": { + "type": "number" + }, + "date_of_session": { + "type": "string" + }, + "session_type": { + "type": "string" + }, + "session_conducted": { + "type": "string" + }, + "duration_of_sessions_attended_in_minutes": { + "type": "string" + }, + "mentor_rating": { + "type": "string" + } + } + } + }, + "filters": { + "type": "object", + "properties": { + "sessions_title": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "sessions_created_by": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "number_of_mentees": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "date_of_session": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "session_type": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "session_conducted": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "duration_of_sessions_attended_in_minutes": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "mentor_rating": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + } + } + }, + "reportsDownloadUrl": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_reports_filterList": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "entity_types": { + "type": "object", + "properties": { + "type": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "parent_id": { + "type": "null" + }, + "organization_id": { + "type": "string" + }, + "entities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "entity_type_id": { + "type": "number" + }, + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "type": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + }, + "required": [ + "id", + "entity_type_id", + "value", + "label", + "status", + "type", + "created_by", + "updated_by", + "created_at", + "updated_at", + "deleted_at" + ] + } + } + } + } + }, + "categories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "label": { + "type": "string" + }, + "value": { + "type": "string" + }, + "parent_id": { + "type": "null" + }, + "organization_id": { + "type": "string" + }, + "entities": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "entity_type_id": { + "type": "number" + }, + "value": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "type": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + } + }, + "required": [ + "id", + "entity_type_id", + "value", + "label", + "status", + "type", + "created_by", + "updated_by", + "created_at", + "updated_at", + "deleted_at" + ] + } + } + } + } + } + } + }, + "roles": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "label": { + "type": "string" + }, + "user_type": { + "type": "number" + }, + "status": { + "type": "string" + }, + "organization_id": { + "type": "number" + }, + "visibility": { + "type": "string" + } + }, + "required": ["id", "title", "label", "user_type", "status", "organization_id", "visibility"] + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/requestSessions/requestSessions.specs.js b/src/integration-tests-new/requestSessions/requestSessions.specs.js new file mode 100644 index 000000000..fb0e9a51d --- /dev/null +++ b/src/integration-tests-new/requestSessions/requestSessions.specs.js @@ -0,0 +1,295 @@ +jest.setTimeout(60000) // Set default timeout to 30 seconds +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') +let menteeDetails = null // This user will make the request +let mentorDetails = null // This user will be the requestee +const schemas = require('./schemas/requestSessions.schemas.json') + +beforeAll(async () => { + console.log('setting up global variables....') + // Log in both a mentee and a mentor for the test + menteeDetails = await commonHelper.logIn() + mentorDetails = await commonHelper.mentorLogIn() + /* + let profileCreate = await request(BASE).post('/mentoring/v1/profile/create').set('x-auth-token', userDetails.token).send({ + designation: ['beo', 'deo', 'testt'], + area_of_expertise: ['educational_leadership', 'sqaa'], + education_qualification: 'MBA', + tags: ['Experienced', 'Technical'], + visibility: 'visible', + organisation_ids: [1], + external_session_visibility: 'CURRENT', + external_mentor_visibility: 'ALL', + }) + + console.log(profileCreate.body, 'profileCreatebody') + */ +}) + +describe('Session Request Lifecycle', () => { + let createdRequestSessionId + + describe('Create Session Request', () => { + test('POST /mentoring/v1/requestSessions/create - should return 201 on successful creation', async () => { + const url = `/mentoring/v1/requestSessions/create` // Removed query parameters + + // Create dynamic start and end dates + const now = new Date() + const startDate = new Date(now) + startDate.setDate(now.getDate() + 10) // 5 days in the future + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) // 1 hour duration + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + let req = request(BASE).post(url) + req = req + .set('x-auth-token', menteeDetails.token) // Use mentee's token + .set('org-id', menteeDetails.organizations[0]) // Correctly access the org ID string + .set('timezone', 'Asia/Calcutta') // Add timezone header + .send({ + title: 'test request session via jest', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + agenda: 'Dynamic agenda to teach chess basics', + requestee_id: mentorDetails.userId.toString(), // Use mentor's ID as the requestee + time_zone: 'Asia/Calcutta', + }) + + const res = await req + + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_requestSessions_create'] + expect(res.body).toMatchSchema(schema) + createdRequestSessionId = res.body.result.id // Capture the created request ID + expect(createdRequestSessionId).toBeDefined() + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/requestSessions/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', menteeDetails.token) + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('Accept Session Request', () => { + test('POST /mentoring/v1/requestSessions/accept - should return 201 when mentor accepts', async () => { + const url = `/mentoring/v1/requestSessions/accept?SkipValidation=true` + let req = request(BASE).post(url) + req = req + .set('x-auth-token', mentorDetails.token) // Use mentor's token to accept + .set('org-id', mentorDetails.organizations[0].id.toString()) // Correctly access the org ID string + .set('timezone', 'Asia/Calcutta') // Add timezone header + .send({ + request_session_id: createdRequestSessionId.toString(), + }) + + const res = await req + expect(res.status).toBe(201) + // validate response schema + expect(res.body).toMatchSchema(schemas['POST_mentoring_v1_requestSessions_accept']) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/accept` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) + +describe('Session Request Rejection Lifecycle', () => { + let createdRequestSessionId + + // This test creates a new session request that will be used in the rejection test below. + // It's good practice to isolate test lifecycles (e.g., accept vs. reject). + test('POST /mentoring/v1/requestSessions/create - should create a new request to be rejected', async () => { + const url = `/mentoring/v1/requestSessions/create` + + const now = new Date() + const startDate = new Date(now) + startDate.setDate(now.getDate() + 15) // 15 days in the future to avoid conflicts + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const res = await request(BASE) + .post(url) + .set('x-auth-token', menteeDetails.token) + .set('org-id', menteeDetails.organizations[0]) + .set('timezone', 'Asia/Calcutta') + .send({ + title: 'test request session for rejection via jest', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + agenda: 'Dynamic agenda to test rejection flow', + requestee_id: mentorDetails.userId.toString(), + time_zone: 'Asia/Calcutta', + }) + + expect(res.status).toBe(201) + createdRequestSessionId = res.body.result.id + expect(createdRequestSessionId).toBeDefined() + }) + + describe('Reject Session Request', () => { + test('POST /mentoring/v1/requestSessions/reject - should return 201 when mentor rejects', async () => { + const url = `/mentoring/v1/requestSessions/reject` + const res = await request(BASE) + .post(url) + .set('x-auth-token', mentorDetails.token) // Mentor's token to reject + .set('org-id', mentorDetails.organizations[0].id.toString()) + .send({ + request_session_id: createdRequestSessionId.toString(), + reject_reason: 'Scheduling conflict.', + }) + + expect(res.status).toBe(201) + + expect(res.body).toMatchSchema(schemas['POST_mentoring_v1_requestSessions_reject']) + }) + }) +}) + +describe('Standalone requestSessions endpoints', () => { + describe('GET /mentoring/v1/requestSessions/list', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/requestSessions/list?pageNo=1&pageSize=5` + let req = request(BASE).get(url) + req = req.set('x-auth-token', menteeDetails.token) + const res = await req + + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_requestSessions_list'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/list?pageNo=1&pageSize=5` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) + + /* + describe('GET /mentoring/v1/requestSessions/getDetails', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/requestSessions/getDetails?request_session_id=string`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "test-token"); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['GET_mentoring_v1_requestSessions_getDetails']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/getDetails?request_session_id=string`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + }); + + describe('GET /mentoring/v1/requestSessions/userAvailability', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/requestSessions/userAvailability?pageNo=string&pageSize=string&status=string&start_date=string&end_date=string`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', "test-token"); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['GET_mentoring_v1_requestSessions_userAvailability']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/userAvailability?pageNo=string&pageSize=string&status=string&start_date=string&end_date=string`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + }); + + describe('POST /mentoring/v1/requestSessions/accept', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/requestSessions/accept`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', "test-token"); + req = req.send({ + "request_session_id": "string" +}).set('Content-Type', 'application/json'); + const res = await req; + expect(res.status).toBe(201); + // validate response schema + const schema = schemas['POST_mentoring_v1_requestSessions_accept']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/accept`; + const res = await request(BASE).post(url); + expect([401,403]).toContain(res.status); + }); + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/requestSessions/accept`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', "test-token"); + req = req.send({}).set('Content-Type', 'application/json'); + const res = await req; + expect([400,422]).toContain(res.status); + }); + + }); + + describe('POST /mentoring/v1/requestSessions/reject', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/requestSessions/reject`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', "test-token"); + req = req.send({ + "request_session_id": "string" +}).set('Content-Type', 'application/json'); + const res = await req; + expect(res.status).toBe(201); + // validate response schema + const schema = schemas['POST_mentoring_v1_requestSessions_reject']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/requestSessions/reject`; + const res = await request(BASE).post(url); + expect([401,403]).toContain(res.status); + }); + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/requestSessions/reject`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', "test-token"); + req = req.send({}).set('Content-Type', 'application/json'); + const res = await req; + expect([400,422]).toContain(res.status); + }); + + }); + + */ +}) diff --git a/src/integration-tests-new/requestSessions/schemas/requestSessions.schemas.json b/src/integration-tests-new/requestSessions/schemas/requestSessions.schemas.json new file mode 100644 index 000000000..7fa797bb4 --- /dev/null +++ b/src/integration-tests-new/requestSessions/schemas/requestSessions.schemas.json @@ -0,0 +1,540 @@ +{ + "POST_mentoring_v1_requestSessions_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "id": { + "type": "number" + }, + "requestor_id": { + "type": "string" + }, + "requestee_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "agenda": { + "type": "string" + }, + "start_date": { + "type": "number" + }, + "end_date": { + "type": "number" + }, + "created_by": { + "type": "string" + }, + "updated_by": { + "type": "string" + }, + "meta": { + "type": "null" + }, + "session_id": { + "type": "null" + }, + "reject_reason": { + "type": "null" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_requestSessions_list": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "requestor_id": { + "type": "string" + }, + "requestee_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": ["object", "null"] + }, + "title": { + "type": "string" + }, + "agenda": { + "type": "string" + }, + "start_date": { + "type": "number" + }, + "end_date": { + "type": "number" + }, + "session_id": { + "type": ["string", "null"] + }, + "reject_reason": { + "type": "null" + }, + "updated_by": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "user_details": { + "type": "object", + "properties": { + "user_id": { + "type": "string" + }, + "image": { + "type": "string" + }, + "name": { + "type": "string" + }, + "experience": { + "type": ["string", "null"] + }, + "designation": { + "type": ["string", "null"] + }, + "organization_id": { + "type": "string" + } + } + }, + "request_type": { + "type": "string" + } + } + } + }, + "count": { + "type": "number" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_requestSessions_getDetails": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "requestor_id": { + "type": "string" + }, + "requestee_id": { + "type": "string" + }, + "status": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": {} + }, + "title": { + "type": "string" + }, + "agenda": { + "type": "string" + }, + "start_date": { + "type": "number" + }, + "end_date": { + "type": "number" + }, + "session_id": { + "type": "null" + }, + "reject_reason": { + "type": "null" + }, + "updated_by": { + "type": "string" + }, + "created_by": { + "type": "string" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "user_details": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "user_id": { + "type": "string" + }, + "mentee_visibility": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "designation": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "area_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": ["value", "label"] + } + }, + "education_qualification": { + "type": "string" + }, + "meta": { + "type": "null" + }, + "is_mentor": { + "type": "boolean" + }, + "experience": { + "type": "string" + }, + "image": { + "type": "null" + } + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_requestSessions_userAvailability": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "date": { + "type": "string" + }, + "bookedSlots": { + "type": "array", + "items": { + "type": "object", + "properties": { + "startTime": { + "type": "string" + }, + "endTime": { + "type": "string" + }, + "title": { + "type": "string" + } + }, + "required": ["startTime", "endTime", "title"] + } + } + }, + "required": ["date", "bookedSlots"] + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_requestSessions_accept": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_requestSessions_reject": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/role-extension/role-extension.spec.js b/src/integration-tests-new/role-extension/role-extension.spec.js new file mode 100644 index 000000000..055725468 --- /dev/null +++ b/src/integration-tests-new/role-extension/role-extension.spec.js @@ -0,0 +1,104 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/role-extension.schemas.json') + +describe('role-extension endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/role-extension/create', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/role-extension/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.set('x-auth-token', 'test-token') + req = req + .send({ + title: 'string', + label: 'string', + scope: 'string', + organization_id: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_role-extension_create'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/role-extension/create` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/role-extension/create` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.set('x-auth-token', 'test-token') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/role-extension/read', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/role-extension/read?title=mentee` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'bearer {{token}}') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_role-extension_read'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('POST /mentoring/v1/role-extension/update', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/role-extension/update?title=mentee` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req + .send({ + label: 'string', + scope: 'string', + organization_id: 'string', + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_role-extension_update'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/role-extension/update?title=mentee` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'bearer {{token}}') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('DELETE /mentoring/v1/role-extension/delete', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/role-extension/delete?title=mentee` + let req = request(BASE).delete(url) + req = req.set('x-auth-token', TOKEN) + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['DELETE_mentoring_v1_role-extension_delete'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/role-extension/delete?title=mentee` + const res = await request(BASE).delete(url) + expect([401, 403]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/role-extension/schemas/role-extension.schemas.json b/src/integration-tests-new/role-extension/schemas/role-extension.schemas.json new file mode 100644 index 000000000..d3dd9c79c --- /dev/null +++ b/src/integration-tests-new/role-extension/schemas/role-extension.schemas.json @@ -0,0 +1,264 @@ +{ + "POST_mentoring_v1_role-extension_create": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + }, + "status": { + "type": "string" + }, + "title": { + "type": "string" + }, + "label": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "id": { + "type": "number" + }, + "deleted_at": { + "type": "null" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "GET_mentoring_v1_role-extension_read": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_role-extension_update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "label": { + "type": "string" + }, + "status": { + "type": "string" + }, + "scope": { + "type": "string" + }, + "organization_id": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "DELETE_mentoring_v1_role-extension_delete": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "type": { + "type": "string" + }, + "version": { + "type": "number" + } + }, + "required": ["id", "type", "version"] + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/rolePermissionMapping/rolePermissionMapping.spec.js b/src/integration-tests-new/rolePermissionMapping/rolePermissionMapping.spec.js new file mode 100644 index 000000000..da0a27ceb --- /dev/null +++ b/src/integration-tests-new/rolePermissionMapping/rolePermissionMapping.spec.js @@ -0,0 +1,59 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/rolePermissionMapping.schemas.json') + +describe('rolePermissionMapping endpoints generated from api-doc.yaml', () => { + describe('POST /mentoring/v1/rolePermissionMapping/create/{role_id}', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/rolePermissionMapping/create/{role_id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req + .send({ + permission_id: 1, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_rolePermissionMapping_create_role_id'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/rolePermissionMapping/create/{role_id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', 'string') + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) + + describe('POST /mentoring/v1/rolePermissionMapping/delete/{role_id}', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/rolePermissionMapping/delete/{role_id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', TOKEN) + req = req + .send({ + permission_id: 1, + }) + .set('Content-Type', 'application/json') + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_mentoring_v1_rolePermissionMapping_delete_role_id'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 400/422 for invalid body', async () => { + const url = `/mentoring/v1/rolePermissionMapping/delete/{role_id}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', TOKEN) + req = req.send({}).set('Content-Type', 'application/json') + const res = await req + expect([400, 422]).toContain(res.status) + }) + }) +}) diff --git a/src/integration-tests-new/rolePermissionMapping/schemas/rolePermissionMapping.schemas.json b/src/integration-tests-new/rolePermissionMapping/schemas/rolePermissionMapping.schemas.json new file mode 100644 index 000000000..af20cf77d --- /dev/null +++ b/src/integration-tests-new/rolePermissionMapping/schemas/rolePermissionMapping.schemas.json @@ -0,0 +1,72 @@ +{ + "POST_mentoring_v1_rolePermissionMapping_create_role_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "roleId": { + "type": "number" + }, + "permissionId": { + "type": "number" + }, + "module": { + "type": "string" + }, + "request_type": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_mentoring_v1_rolePermissionMapping_delete_role_id": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": {} + }, + "meta": { + "type": "object", + "properties": { + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + } +} diff --git a/src/integration-tests-new/sessions/schemas/sessions.schemas.json b/src/integration-tests-new/sessions/schemas/sessions.schemas.json new file mode 100644 index 000000000..036d27661 --- /dev/null +++ b/src/integration-tests-new/sessions/schemas/sessions.schemas.json @@ -0,0 +1,499 @@ +{ + "GET_/mentoring/v1/sessions/list": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "count": { + "type": "number" + }, + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "mentor_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "meeting_info.value": { + "type": "string" + }, + "meeting_info.platform": { + "type": "string" + }, + "mentor_name": { + "type": "string" + }, + "organization_id": { + "type": "string" + } + } + } + } + } + } + } + }, + "GET_/mentoring/v1/sessions/details/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "mentor_id": { + "type": "string" + }, + "description": { + "type": "string" + }, + "status": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "created_at": { + "type": "string" + }, + "session_reschedule_count": { + "type": "number" + }, + "time_zone": { + "type": "string" + }, + "started_at": { + "type": "string" + }, + "completed_at": { + "type": "string" + }, + "is_feedback_skipped": { + "type": "boolean" + }, + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "meeting_info": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "platform": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": {} + }, + "visibility": { + "type": "string" + }, + "organization_ids": { + "type": "string" + }, + "mentor_organization_id": { + "type": "string" + }, + "seats_remaining": { + "type": "number" + }, + "seats_limit": { + "type": "number" + }, + "updated_at": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "is_enrolled": { + "type": "boolean" + }, + "mentor_name": { + "type": "string" + }, + "organization_id": { + "type": "array", + "items": { + "type": "number" + } + } + } + }, + "meta": { + "type": "object", + "properties": {} + } + } + }, + "GET_/mentoring/v1/sessions/share/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "share_link": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": {} + } + } + }, + "GET_/mentoring/v1/mentees/joinSession/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "platform": { + "type": "string" + }, + "link": { + "type": "string" + } + } + }, + "meta": { + "type": "object", + "properties": { + "formsVersion": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { "type": "number" }, + "type": { "type": "string" }, + "version": { "type": "number" } + } + } + }, + "correlation": { + "type": "string" + }, + "meetingPlatform": { + "type": "string" + } + } + } + } + }, + "POST_/mentoring/v1/sessions/enroll/{sessionId}": {}, + "POST_/mentoring/v1/sessions/unenroll/{sessionId}": {}, + "GET_/mentoring/v1/sessions/start/{sessionId}": {}, + "POST_/mentoring/v1/sessions/update": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "recommended_for": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "categories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "medium": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "mentor_id": { + "type": "string" + }, + "mentor_name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "is_feedback_skipped": { + "type": "boolean" + }, + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "id": { + "type": "number" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + } + } + }, + "DELETE_/mentoring/v1/sessions/update/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "string" + } + }, + "meta": { + "type": "object", + "properties": {} + } + } + }, + "POST_/mentoring/v1/sessions/update/{sessionId}": { + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "start_date": { + "type": "string" + }, + "end_date": { + "type": "string" + }, + "recommended_for": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "categories": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "medium": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "image": { + "type": "array", + "items": { + "type": "string" + } + }, + "mentor_id": { + "type": "string" + }, + "mentor_name": { + "type": "string" + }, + "status": { + "type": "string" + }, + "deleted_at": { + "type": "null" + }, + "is_feedback_skipped": { + "type": "boolean" + }, + "mentee_feedback_question_set": { + "type": "string" + }, + "mentor_feedback_question_set": { + "type": "string" + }, + "id": { + "type": "number" + }, + "created_at": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + } + } + }, + "GET_/mentoring/v1/sessions/getRecording/{sessionId}": {}, + "PATCH_/mentoring/v1/sessions/completed/{sessionId}": {}, + "PATCH_/mentoring/v1/sessions/updateRecordingUrl/{internalSessionId}": {} +} diff --git a/src/integration-tests-new/sessions/sessions.specs.js b/src/integration-tests-new/sessions/sessions.specs.js new file mode 100644 index 000000000..7c25535ed --- /dev/null +++ b/src/integration-tests-new/sessions/sessions.specs.js @@ -0,0 +1,552 @@ +jest.setTimeout(100000) +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const commonHelper = require('@commonTests') + +let userDetails = null +let menteeDetails = null + +const schemas = require('./schemas/sessions.schemas.json') + +beforeAll(async () => { + userDetails = await commonHelper.mentorLogIn() // Log in a mentor user + menteeDetails = await commonHelper.logIn() // Log in a second user to act as a mentee (menteeDetails) + + console.log(userDetails) + console.log(menteeDetails) + console.log('line 18') +}) + +describe('sessions endpoints generated from api-doc.yaml', () => { + describe('Session Details Lifecycle', () => { + let createdSessionId + + beforeAll(async () => { + // Create a session to be used in the tests + const now = new Date() + const startDate = new Date(now) + startDate.setDate(now.getDate() + 3) + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createUrl = `/mentoring/v1/sessions/update` + const createRes = await request(BASE).post(createUrl).set('x-auth-token', userDetails.token).send({ + title: 'test nov 27', + description: 'desc', + type: 'PUBLIC', + mentees: [], + start_date: startDateTimestamp, + end_date: endDateTimestamp, + recommended_for: [], + categories: [], + medium: [], + time_zone: 'Asia/Calcutta', + mentor_id: userDetails.userId.toString(), + }) + + // Assuming 201 is the success status for creation + expect(createRes.status).toBe(201) + createdSessionId = createRes.body.result.id + expect(createdSessionId).toBeDefined() + }) + + afterAll(async () => { + // Clean up the created session + if (createdSessionId) { + const deleteUrl = `/mentoring/v1/sessions/update/${createdSessionId}` + // We don't need to assert the result of cleanup, but it's good practice to ensure it runs + // await request(BASE).delete(deleteUrl).set('x-auth-token', userDetails.token) + } + }) + + test('GET /mentoring/v1/sessions/details/{sessionId} - should return 200 on success', async () => { + const url = `/mentoring/v1/sessions/details/${createdSessionId}` + let req = request(BASE).get(url) + req = req.set('x-auth-token', userDetails.token) // Make the API call + const res = await req + expect(res.status).toBe(201) + }) + + test('GET /mentoring/v1/sessions/details/{sessionId} - should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/details/${createdSessionId}` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + + test('POST /mentoring/v1/sessions/enroll/{sessionId} - should return 200 on successful enrollment', async () => { + const url = `/mentoring/v1/sessions/enroll/${createdSessionId}` + let req = request(BASE).post(url) + req = req.set('x-auth-token', menteeDetails.token).set('timezone', 'Asia/Calcutta') // Use mentee's token and add timezone // Make the API call + const res = await req + expect(res.status).toBe(201) + // validate response schema + const schema = schemas['POST_/mentoring/v1/sessions/enroll/{sessionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('POST /mentoring/v1/sessions/enroll/{sessionId} - should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/enroll/${createdSessionId}` + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + + test('POST /mentoring/v1/sessions/unenroll/{sessionId} - should return 200 on successful unenrollment', async () => { + const url = `/mentoring/v1/sessions/unEnroll/${createdSessionId}` // Corrected to camelCase 'unEnroll' + let req = request(BASE).post(url) + req = req.set('x-auth-token', menteeDetails.token) // Use mentee's token to unenroll // Make the API call + const res = await req + expect(res.status).toBe(202) + // validate response schema + const schema = schemas['POST_/mentoring/v1/sessions/unenroll/{sessionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('POST /mentoring/v1/sessions/unenroll/{sessionId} - should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/unEnroll/${createdSessionId}` // Corrected to camelCase 'unEnroll' + const res = await request(BASE).post(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('GET /mentoring/v1/sessions/start/{sessionId}', () => { + test('should return 200 on successful session start', async () => { + let mentorDetails = await commonHelper.mentorLogIn() + // Step 1: Create a session that is scheduled to start now + const now = new Date() + const startDate = new Date(now.getTime() - 10 * 1000) // 10 seconds ago + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createRes = await request(BASE) + .post('/mentoring/v1/sessions/update') + .set('x-auth-token', mentorDetails.token) + .send({ + title: 'Session to be started', + description: 'desc', + type: 'PUBLIC', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + time_zone: 'Asia/Calcutta', + mentor_id: mentorDetails.userId.toString(), + }) + + expect(createRes.status).toBe(201) + const createdSessionId = createRes.body.result.id + + // Step 2: Start the created session + const url = `/mentoring/v1/sessions/start/${createdSessionId}` + let req = request(BASE).get(url) + req = req.set('x-auth-token', mentorDetails.token) // Make the API call + const res = await req + expect(res.status).toBe(200) + const schema = schemas['GET_/mentoring/v1/sessions/start/{sessionId}'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/mentees/joinSession/{sessionId}', () => { + test('should return 200 when a mentee joins a started session', async () => { + const mentorDetails = await commonHelper.mentorLogIn() + const menteeDetails = await commonHelper.logIn() + + // Step 1: Mentor creates a session scheduled to start now + const now = new Date() + const startDate = new Date(now.getTime() - 10 * 1000) // 10 seconds ago + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createRes = await request(BASE) + .post('/mentoring/v1/sessions/update') + .set('x-auth-token', mentorDetails.token) // Mentor's token + .send({ + title: 'Session to be Joined', + description: 'desc', + type: 'PUBLIC', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + time_zone: 'Asia/Calcutta', + mentor_id: mentorDetails.userId.toString(), + }) + expect(createRes.status).toBe(201) + const sessionId = createRes.body.result.id + + // Step 2: Mentor starts the session + const startRes = await request(BASE) + .get(`/mentoring/v1/sessions/start/${sessionId}`) + .set('x-auth-token', mentorDetails.token) + + // Step 3: Mentee enrolls in the session + const enrollUrl = `/mentoring/v1/sessions/enroll/${sessionId}` + const enrollRes = await request(BASE) + .post(enrollUrl) + .set('x-auth-token', menteeDetails.token) + .set('timezone', 'Asia/Calcutta') + expect(enrollRes.status).toBe(201) + + // Step 4: Mentee joins the session + const url = `/mentoring/v1/mentees/joinSession/${sessionId}` + let req = request(BASE).get(url) + req = req.set('x-auth-token', menteeDetails.token) // Mentee's token + req = req.set('org-id', menteeDetails.organizations[0].id.toString()) + req = req.set('timezone', 'Asia/Calcutta') + + const res = await req + expect(res.status).toBe(200) + + const schema = schemas['GET_/mentoring/v1/mentees/joinSession/{sessionId}'] + expect(res.body).toMatchSchema(schema) + }) + + test('should return 401/403 when trying to join without a token', async () => { + const mentorDetails = await commonHelper.mentorLogIn() + + // Step 1: Mentor creates a session + const now = new Date() + const startDate = new Date(now.getTime() - 10 * 1000) // 10 seconds ago + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + const endDate = new Date(startDate) + endDate.setHours(startDate.getHours() + 1) + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createRes = await request(BASE) + .post('/mentoring/v1/sessions/update') + .set('x-auth-token', mentorDetails.token) + .send({ + title: 'Session for unauthorized join test', + description: 'desc', + type: 'PUBLIC', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + time_zone: 'Asia/Calcutta', + mentor_id: mentorDetails.userId.toString(), + }) + expect(createRes.status).toBe(201) + const sessionId = createRes.body.result.id + + // Step 2: Attempt to join the session without a token + const url = `/mentoring/v1/mentees/joinSession/${sessionId}` + const res = await request(BASE).get(url) + expect([401, 403]).toContain(res.status) + }) + }) + + describe('PATCH /mentoring/v1/sessions/completed/{sessionId}', () => { + let sessionId + + beforeAll(async () => { + // Create a session that has passed to mark as complete + const now = new Date() + const startDate = new Date(now.getTime() - 2 * 60 * 60 * 1000) // 2 hours ago + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + const endDate = new Date(startDate.getTime() + 60 * 60 * 1000) // 1 hour duration + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createRes = await request(BASE) + .post('/mentoring/v1/sessions/update') + .set('x-auth-token', userDetails.token) + .send({ + title: 'Session to be completed', + description: 'This session is created to test the completion endpoint.', + type: 'PUBLIC', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + time_zone: 'Asia/Calcutta', + mentor_id: userDetails.userId.toString(), + }) + + expect(createRes.status).toBe(201) + sessionId = createRes.body.result.id + }) + + test('should return 200 on success', async () => { + // First, start the session + const startUrl = `/mentoring/v1/sessions/start/${sessionId}` + const startRes = await request(BASE).get(startUrl).set('x-auth-token', userDetails.token) + expect(startRes.status).toBe(200) + + // Then, mark the session as completed + const url = `/mentoring/v1/sessions/completed/${sessionId}` + let req = request(BASE).patch(url) + req = req.set('x-auth-token', userDetails.token) // Make the API call + const res = await req + expect(res.status).toBe(200) + // const schema = schemas['PATCH_/mentoring/v1/sessions/completed/{sessionId}'] + // expect(res.body).toMatchSchema(schema) + }) + }) + + describe('Session Feedback Submission', () => { + let feedbackSessionId + + beforeAll(async () => { + let userDetails = await commonHelper.mentorLogIn() + // Create a session that has passed to mark as complete + const now = new Date() + const startDate = new Date(now.getTime() - 2 * 60 * 60 * 1000) // 2 hours ago + const startDateTimestamp = Math.floor(startDate.getTime() / 1000) + const endDate = new Date(startDate.getTime() + 60 * 60 * 1000) // 1 hour duration + const endDateTimestamp = Math.floor(endDate.getTime() / 1000) + + const createRes = await request(BASE) + .post('/mentoring/v1/sessions/update') + .set('x-auth-token', userDetails.token) + .send({ + title: 'Session for Feedback Test', + description: 'This session is created to test the feedback endpoint.', + type: 'PUBLIC', + start_date: startDateTimestamp, + end_date: endDateTimestamp, + time_zone: 'Asia/Calcutta', + mentor_id: userDetails.userId.toString(), + }) + + expect(createRes.status).toBe(201) + feedbackSessionId = createRes.body.result.id + + // Enroll mentee in the session + const enrollUrl = `/mentoring/v1/sessions/enroll/${feedbackSessionId}` + const enrollRes = await request(BASE) + .post(enrollUrl) + .set('x-auth-token', menteeDetails.token) + .set('timezone', 'Asia/Calcutta') + expect(enrollRes.status).toBe(201) + + // Start the session + const startUrl = `/mentoring/v1/sessions/start/${feedbackSessionId}` + const startRes = await request(BASE).get(startUrl).set('x-auth-token', userDetails.token) + expect(startRes.status).toBe(200) + + // Complete the session + const completeUrl = `/mentoring/v1/sessions/completed/${feedbackSessionId}` + const completeRes = await request(BASE).patch(completeUrl).set('x-auth-token', userDetails.token) + expect(completeRes.status).toBe(200) + }) + + test('POST /mentoring/v1/feedback/submit/{sessionId} - mentee feedback should return 200', async () => { + const url = `/mentoring/v1/feedback/submit/${feedbackSessionId}` + const menteeFeedbackPayload = { + feedbacks: [ + { question_id: 3, value: 3, label: 'How would you rate the host of the session?' }, + { question_id: 4, value: 4, label: 'How would you rate the engagement in the session?' }, + ], + feedback_as: 'mentee', + } + const res = await request(BASE) + .post(url) + .set('x-auth-token', menteeDetails.token) + .send(menteeFeedbackPayload) + expect(res.status).toBe(200) + }) + + test('POST /mentoring/v1/feedback/submit/{sessionId} - mentor feedback should return 200', async () => { + const url = `/mentoring/v1/feedback/submit/${feedbackSessionId}` + const mentorFeedbackPayload = { + feedbacks: [ + { question_id: 1, value: 4, label: 'How would you rate the engagement in the session?' }, + { question_id: 2, value: 3, label: 'How would you rate the Audio/Video quality?' }, + ], + feedback_as: 'mentor', + } + const res = await request(BASE).post(url).set('x-auth-token', userDetails.token).send(mentorFeedbackPayload) + expect(res.status).toBe(200) + }) + }) + /* + describe('GET /mentoring/v1/sessions/list', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/sessions/list?page=1&limit=2&status=PUBLISHED, COMPLETED&search=John&recommended_for=string`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', userDetails.token); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['GET_/mentoring/v1/sessions/list']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/list?page=1&limit=2&status=PUBLISHED, COMPLETED&search=John&recommended_for=string`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('GET /mentoring/v1/sessions/share/{sessionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/sessions/share/1`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', userDetails.token); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['GET_/mentoring/v1/sessions/share/{sessionId}']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/share/1`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + */ + /* + describe('POST /mentoring/v1/sessions/update', () => { + test('should return 201', async () => { + const url = `/mentoring/v1/sessions/update`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', userDetails.token); + req = req.send({ + "title": "Leadership session by Adam", + "description": "Leadership session desc", + "start_date": "1695210731", + "end_date": "1695214329", + "mentee_feedback_question_set": "MENTEE_QS1", + "mentor_feedback_question_set": "MENTOR_QS2", + "recommended_for": [ + "deo" + ], + "categories": [ + "educational_leadership" + ], + "medium": [ + "en" + ], + "image": [ + "users/1232s2133sdd1-12e2dasd3123.png" + ] + }).set('Content-Type', 'application/json'); + const res = await req; + expect(res.status).toBe(201); + // validate response schema + const schema = schemas['POST_/mentoring/v1/sessions/update']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/update`; + const res = await request(BASE).post(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('DELETE /mentoring/v1/sessions/update/{sessionId}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/sessions/update/1`; + let req = request(BASE).delete(url); + req = req.set('x-auth-token', userDetails.token); + const res = await req; + expect(res.status).toBe(202); + // validate response schema + const schema = schemas['DELETE_/mentoring/v1/sessions/update/{sessionId}']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/update/1`; + const res = await request(BASE).delete(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('POST /mentoring/v1/sessions/update/{sessionId}', () => { + test('should return 202', async () => { + const url = `/mentoring/v1/sessions/update/1`; + let req = request(BASE).post(url); + req = req.set('x-auth-token', userDetails.token); + req = req.send({ + "title": "Leadership session by Adam", + "description": "Leadership session desc", + "start_date": "1695210731", + "end_date": "1695214329", + "mentee_feedback_question_set": "MENTEE_QS1", + "mentor_feedback_question_set": "MENTOR_QS2", + "recommended_for": [ + "deo" + ], + "categories": [ + "educational_leadership" + ], + "medium": [ + "en" + ], + "image": [ + "users/1232s2133sdd1-12e2dasd3123.png" + ] + }).set('Content-Type', 'application/json'); + const res = await req; + expect(res.status).toBe(202); + // validate response schema + const schema = schemas['POST_/mentoring/v1/sessions/update/{sessionId}']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/update/1`; + const res = await request(BASE).post(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('GET /mentoring/v1/sessions/getRecording/{sessionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/sessions/getRecording/1`; + let req = request(BASE).get(url); + req = req.set('x-auth-token', userDetails.token); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['GET_/mentoring/v1/sessions/getRecording/{sessionId}']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/getRecording/1`; + const res = await request(BASE).get(url); + expect([401,403]).toContain(res.status); + }); + + + }); + + describe('PATCH /mentoring/v1/sessions/updateRecordingUrl/{internalSessionId}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/sessions/updateRecordingUrl/1`; + let req = request(BASE).patch(url); + req = req.set('x-auth-token', userDetails.token); + const res = await req; + expect(res.status).toBe(200); + // validate response schema + const schema = schemas['PATCH_/mentoring/v1/sessions/updateRecordingUrl/{internalSessionId}']; + expect(res.body).toMatchSchema(schema); + }); + + test('should return 401/403 when unauthorized', async () => { + const url = `/mentoring/v1/sessions/updateRecordingUrl/1`; + const res = await request(BASE).patch(url); + expect([401,403]).toContain(res.status); + }); + + + }); +*/ +}) diff --git a/src/integration-tests-new/testSequencer.js b/src/integration-tests-new/testSequencer.js new file mode 100644 index 000000000..334e662be --- /dev/null +++ b/src/integration-tests-new/testSequencer.js @@ -0,0 +1,57 @@ +const Sequencer = require('@jest/test-sequencer').default +const path = require('path') + +class CustomSequencer extends Sequencer { + sort(tests) { + // Define exact execution order (must match actual filenames) + const executionOrder = [ + 'mentees/mentees.specs.js', + 'mentors/mentors.specs.js', + 'connections/connections.specs.js', + 'entity/entity.specs.js', + 'entity-type/entity-type.specs.js', + 'form/form.specs.js', + 'profile/profile.specs.js', + 'requestSessions/requestSessions.specs.js', + 'sessions/sessions.specs.js', + 'default-rule/default-rule.specs.js', + ] + + // Map tests to their relative paths + const testMap = {} + tests.forEach((test) => { + const relPath = path.relative(path.join(process.cwd(), 'integration-tests-new'), test.path) + testMap[relPath] = test + }) + + // Create ordered test array + const orderedTests = [] + executionOrder.forEach((testPath) => { + if (testMap[testPath]) { + orderedTests.push(testMap[testPath]) + delete testMap[testPath] + } else { + console.warn(`⚠️ Test not found: ${testPath}`) + } + }) + + // Add any remaining tests at the end + const remainingTests = Object.values(testMap) + if (remainingTests.length) { + console.warn( + '⚠️ These tests were not in the execution order:', + remainingTests.map((t) => path.relative(path.join(process.cwd(), 'integration-tests'), t.path)) + ) + orderedTests.push(...remainingTests) + } + + console.log('✅ Final execution order:') + orderedTests.forEach((test, index) => { + console.log(`${index + 1}. ${path.relative(path.join(process.cwd(), 'integration-tests'), test.path)}`) + }) + + return orderedTests + } +} + +module.exports = CustomSequencer diff --git a/src/integration-tests-new/users/schemas/users.schemas.json b/src/integration-tests-new/users/schemas/users.schemas.json new file mode 100644 index 000000000..01fa87e27 --- /dev/null +++ b/src/integration-tests-new/users/schemas/users.schemas.json @@ -0,0 +1,100 @@ +{ + "GET_mentoring_v1_users_pendingFeedbacks": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "title": { + "type": "string" + }, + "description": { + "type": "string" + }, + "mentor_feedback_form": { + "type": "string" + }, + "form": { + "type": "object", + "properties": {} + } + } + } + } + } + }, + "GET_mentoring_v1_users_list_type_userType_page_page_limit_limit_search_search": { + "$schema": "http://json-schema.org/draft-04/schema#", + "type": "object", + "properties": { + "responseCode": { + "type": "string" + }, + "message": { + "type": "string" + }, + "result": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "values": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "areas_of_expertise": { + "type": "array", + "items": { + "type": "object", + "properties": { + "value": { + "type": "string" + }, + "label": { + "type": "string" + } + } + } + }, + "image": { + "type": "string" + } + } + } + } + } + } + }, + "count": { + "type": "number" + } + } + } + } + } +} diff --git a/src/integration-tests-new/users/users.spec.js b/src/integration-tests-new/users/users.spec.js new file mode 100644 index 000000000..80a14c8b3 --- /dev/null +++ b/src/integration-tests-new/users/users.spec.js @@ -0,0 +1,31 @@ +const request = require('supertest') +const BASE = process.env.BASE_URL || 'http://localhost:3000' +const schemas = require('./schemas/users.schemas.json') + +describe('users endpoints generated from api-doc.yaml', () => { + describe('GET /mentoring/v1/users/pendingFeedbacks', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/users/pendingFeedbacks` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_users_pendingFeedbacks'] + expect(res.body).toMatchSchema(schema) + }) + }) + + describe('GET /mentoring/v1/users/list?type={userType}&page={page}&limit={limit}&search={search}', () => { + test('should return 200', async () => { + const url = `/mentoring/v1/users/list?type=mentor&page=1&limit=2&search=jhon` + let req = request(BASE).get(url) + req = req.set('x-auth-token', 'string') + const res = await req + expect(res.status).toBe(200) + // validate response schema + const schema = schemas['GET_mentoring_v1_users_list_type_userType_page_page_limit_limit_search_search'] + expect(res.body).toMatchSchema(schema) + }) + }) +}) diff --git a/src/integrationJest.config.js b/src/integrationJest.config.js index 79e092584..11cc5985e 100644 --- a/src/integrationJest.config.js +++ b/src/integrationJest.config.js @@ -15,9 +15,12 @@ module.exports = { '@constants/(.*)': '/constants/$1', '@configs/(.*)': '/configs/$1', '@health-checks/(.*)': '/health-checks/$1', - '@commonTests': '/integration-tests/commonTests', + '@commonTests': '/integration-tests-new/commonTests', + '@helpers/(.*)': '/helpers/$1', + '@utils/(.*)': '/utils/$1', }, - testMatch: ['/integration-tests/**/*.spec.js'], + testMatch: ['/integration-tests-new/**/*.specs.js'], + testSequencer: '/integration-tests-new/testSequencer', reporters: ['default', ['jest-junit', { suiteName: 'jest tests', outputDirectory: '../dev-ops/report' }]], } /* Add env variables used by jest here because jest do not have access to app or docker env files. diff --git a/src/package.json b/src/package.json index a77226f14..0daa0e1ab 100644 --- a/src/package.json +++ b/src/package.json @@ -11,10 +11,11 @@ "start": "NODE_ENV=development nodemon app.js", "prod": "NODE_ENV=production node app.js", "stage": "NODE_ENV=stage node app.js", + "dev": "node app.js", "qa": "NODE_ENV=qa node app.js", "prepare": "cd .. && husky install src/.husky", "test:integration": "jest --verbose ./integration-test --config=integrationJest.config.js --runInBand", - "db:init": "sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check' && sequelize-cli db:migrate ", + "db:init": "(sequelize-cli db:create || echo 'Database already exists or some issue while creating db, Please check') && sequelize-cli db:migrate", "db:seed:all": "sequelize-cli db:seed:all || echo 'Seeded data already exists or some issue while seeding the data, Please check' " }, "author": "Aman Kumar Gupta ", @@ -71,7 +72,7 @@ "@faker-js/faker": "^7.6.0", "eslint": "^8.16.0", "husky": "^8.0.1", - "jest": "^28.1.1", + "jest": "^30.2.0", "jest-json-schema": "^6.1.0", "jest-junit": "^14.0.1", "lint-staged": "^12.4.1", diff --git a/src/setupFileAfterEnv.js b/src/setupFileAfterEnv.js index b5b616467..cfe3b5040 100644 --- a/src/setupFileAfterEnv.js +++ b/src/setupFileAfterEnv.js @@ -6,7 +6,7 @@ const pool = new Pool() expect.extend(matchers) //PostgreSQL connection string -const connectionString = 'postgres://postgres:postgres@localhost:5432/mentoring-local' +const connectionString = 'postgres://postgres:postgres@localhost:5432/elevate-mentoring' // Connect to the PostgreSQL database using the connection string const db = new Client({