diff --git a/.eslintignore b/.eslintignore index 7e39d17d..7b988e61 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,6 +1,7 @@ .jest-cache/* .jest-coverage/* node_modules/* +integration-tests/* **/dist/* **/node_modules/* diff --git a/.github/workflows/action.yml b/.github/workflows/action.yml index 881cb131..6603d068 100644 --- a/.github/workflows/action.yml +++ b/.github/workflows/action.yml @@ -10,6 +10,9 @@ on: jobs: unit-tests: runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x, 15., 16.x] steps: - name: Cancel Previous Runs uses: styfle/cancel-workflow-action@0.9.1 @@ -22,13 +25,54 @@ jobs: fetch-depth: 0 - name: Setup Node.js environment - uses: actions/setup-node@v2.4.1 + uses: actions/setup-node@v3.1.1 with: - node-version: "14" - cache: "npm" + node-version: ${{ matrix.node }} - name: 'npm install' run: npm install - name: 'run unit tests' run: npm run test + + integration-tests: + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [14.x, 15., 16.x] + + services: + postgres: + image: postgres + env: + POSTGRES_PASSWORD: postgres + POSTGRES_USER: postgres + POSTGRES_DB: medusa-extender + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + + steps: + - name: Checkout + uses: actions/checkout@v2.3.5 + with: + fetch-depth: 0 + + - name: Setup Node.js environment + uses: actions/setup-node@v3.1.1 + with: + node-version: ${{ matrix.node }} + + - name: 'prepare packages and install' + run: | + npm i && npm run build && npm pack --pack-destination integration-tests && PACKAGE_NAME=$(cat package.json | grep version | head -1 | awk -F: '{ print "medusa-extender-", $2, ".tgz" }' | sed 's/[ ",]//g') && cd integration-tests && npm i ${PACKAGE_NAME} && npm i + + - name: 'run integration tests' + run: cd integration-tests && npm run test:integration + env: + DB_PASSWORD: postgres + IS_CI: true \ No newline at end of file diff --git a/integration-tests/.gitignore b/integration-tests/.gitignore new file mode 100644 index 00000000..7a7c41e5 --- /dev/null +++ b/integration-tests/.gitignore @@ -0,0 +1,9 @@ +dist +node_modules +tsconfig.tsbuildinfo + +.env +.env.local +.env.test + +package-lock.json \ No newline at end of file diff --git a/integration-tests/data.json b/integration-tests/data.json new file mode 100644 index 00000000..e8409450 --- /dev/null +++ b/integration-tests/data.json @@ -0,0 +1,868 @@ +{ + "store": { + "currencies": ["eur", "usd"] + }, + "users": [ + { + "email": "admin@medusa-test.com", + "password": "supersecret" + } + ], + "regions": [ + { + "id": "test-region-eu", + "name": "EU", + "currency_code": "eur", + "tax_rate": 0, + "payment_providers": ["manual"], + "fulfillment_providers": ["manual"], + "countries": ["gb", "de", "dk", "se", "fr", "es", "it"] + }, + { + "id": "test-region-na", + "name": "NA", + "currency_code": "usd", + "tax_rate": 0, + "payment_providers": ["manual"], + "fulfillment_providers": ["manual"], + "countries": ["us", "ca"] + } + ], + "shipping_options": [ + { + "name": "PostFake Standard", + "region_id": "test-region-eu", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "amount": 1000 + }, + { + "name": "PostFake Express", + "region_id": "test-region-eu", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "amount": 1500 + }, + { + "name": "PostFake Return", + "region_id": "test-region-eu", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "is_return": true, + "amount": 1000 + }, + { + "name": "I want to return it myself", + "region_id": "test-region-eu", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "is_return": true, + "amount": 0 + }, + { + "name": "FakeEx Standard", + "region_id": "test-region-na", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "amount": 800 + }, + { + "name": "FakeEx Express", + "region_id": "test-region-na", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "amount": 1200 + }, + { + "name": "FakeEx Return", + "region_id": "test-region-na", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "is_return": true, + "amount": 800 + }, + { + "name": "I want to return it myself", + "region_id": "test-region-na", + "provider_id": "manual", + "data": { + "id": "manual-fulfillment" + }, + "price_type": "flat_rate", + "is_return": true, + "amount": 0 + } + ], + "products": [ + { + "title": "Medusa T-Shirt", + "subtitle": null, + "description": "Reimagine the feeling of a classic T-shirt. With our cotton T-shirts, everyday essentials no longer have to be ordinary.", + "handle": "t-shirt", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/tee-black-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/tee-black-back.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/tee-white-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/tee-white-back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + }, + { + "title": "Color", + "values": ["Black", "White"] + } + ], + "variants": [ + { + "title": "S / Black", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "S" + }, + { + "value": "Black" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "S / White", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "S" + }, + { + "value": "White" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M / Black", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "M" + }, + { + "value": "Black" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M / White", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "M" + }, + { + "value": "White" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L / Black", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "L" + }, + { + "value": "Black" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L / White", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "L" + }, + { + "value": "White" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL / Black", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "XL" + }, + { + "value": "Black" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL / White", + "prices": [ + { + "currency_code": "eur", + "amount": 1950 + }, + { + "currency_code": "usd", + "amount": 2200 + } + ], + "options": [ + { + "value": "XL" + }, + { + "value": "White" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Sweatshirt", + "subtitle": null, + "description": "Reimagine the feeling of a classic sweatshirt. With our cotton sweatshirt, everyday essentials no longer have to be ordinary.", + "handle": "sweatshirt", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatshirt-vintage-back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + } + ], + "variants": [ + { + "title": "S", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "S" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "M" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "L" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "XL" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Sweatpants", + "subtitle": null, + "description": "Reimagine the feeling of classic sweatpants. With our cotton sweatpants, everyday essentials no longer have to be ordinary.", + "handle": "sweatpants", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/sweatpants-gray-back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + } + ], + "variants": [ + { + "title": "S", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "S" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "M" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "L" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL", + "prices": [ + { + "currency_code": "eur", + "amount": 2950 + }, + { + "currency_code": "usd", + "amount": 3350 + } + ], + "options": [ + { + "value": "XL" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Shorts", + "subtitle": null, + "description": "Reimagine the feeling of classic shorts. With our cotton shorts, everyday essentials no longer have to be ordinary.", + "handle": "shorts", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/shorts-vintage-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/shorts-vintage-back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + } + ], + "variants": [ + { + "title": "S", + "prices": [ + { + "currency_code": "eur", + "amount": 2500 + }, + { + "currency_code": "usd", + "amount": 2850 + } + ], + "options": [ + { + "value": "S" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M", + "prices": [ + { + "currency_code": "eur", + "amount": 2500 + }, + { + "currency_code": "usd", + "amount": 2850 + } + ], + "options": [ + { + "value": "M" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L", + "prices": [ + { + "currency_code": "eur", + "amount": 2500 + }, + { + "currency_code": "usd", + "amount": 2850 + } + ], + "options": [ + { + "value": "L" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL", + "prices": [ + { + "currency_code": "eur", + "amount": 2500 + }, + { + "currency_code": "usd", + "amount": 2850 + } + ], + "options": [ + { + "value": "XL" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Hoodie", + "subtitle": null, + "description": "Reimagine the feeling of a classic hoodie. With our cotton hoodie, everyday essentials no longer have to be ordinary.", + "handle": "hoodie", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/black_hoodie_front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/black_hoodie_back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + } + ], + "variants": [ + { + "title": "S", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "S" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "M" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "L" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "XL" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Longsleeve", + "subtitle": null, + "description": "Reimagine the feeling of a classic longsleeve. With our cotton longsleeve, everyday essentials no longer have to be ordinary.", + "handle": "longsleeve", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/ls-black-front.png", + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/ls-black-back.png" + ], + "options": [ + { + "title": "Size", + "values": ["S", "M", "L", "XL"] + } + ], + "variants": [ + { + "title": "S", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "S" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "M", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "M" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "L", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "L" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + }, + { + "title": "XL", + "prices": [ + { + "currency_code": "eur", + "amount": 3650 + }, + { + "currency_code": "usd", + "amount": 4150 + } + ], + "options": [ + { + "value": "XL" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + }, + { + "title": "Medusa Coffee Mug", + "subtitle": null, + "description": "Every programmer's best friend.", + "handle": "coffee-mug", + "is_giftcard": false, + "weight": 400, + "images": [ + "https://medusa-public-images.s3.eu-west-1.amazonaws.com/coffee-mug.png" + ], + "options": [ + { + "title": "Size", + "values": ["One Size"] + } + ], + "variants": [ + { + "title": "One Size", + "prices": [ + { + "currency_code": "eur", + "amount": 1000 + }, + { + "currency_code": "usd", + "amount": 1200 + } + ], + "options": [ + { + "value": "One Size" + } + ], + "inventory_quantity": 100, + "manage_inventory": true + } + ] + } + ] +} \ No newline at end of file diff --git a/integration-tests/jest.config.js b/integration-tests/jest.config.js new file mode 100644 index 00000000..cae05f9f --- /dev/null +++ b/integration-tests/jest.config.js @@ -0,0 +1,22 @@ +module.exports = { + "testTimeout": 3600000, + "moduleFileExtensions": [ + "js", + "json", + "ts" + ], + "preset": 'ts-jest', + "rootDir": "tests", + "testRegex": ".*\\.spec\\.ts$", + "transformIgnorePatterns": ["/node_modules/"], + "collectCoverageFrom": [ + "**/*.(t|j)s" + ], + "coverageReporters": [ + "json-summary", + "text", + "lcov" + ], + "coverageDirectory": "../coverage", + "testEnvironment": "node" +}; diff --git a/integration-tests/medusa-config.js b/integration-tests/medusa-config.js new file mode 100644 index 00000000..ba49abe1 --- /dev/null +++ b/integration-tests/medusa-config.js @@ -0,0 +1,28 @@ +require('dotenv').config(); + +const DB_PASSWORD = process.env.DB_PASSWORD ?? ''; +const DB_USER = process.env.DB_USER ?? 'postgres'; +const DB_HOST = process.env.DB_HOST ?? 'localhost'; +const DB_PORT = process.env.DB_PORT ?? 5432; + +const isCI = !!process.env.IS_CI; + +const DB_URL = isCI + ? `postgres://${DB_USER}:${DB_PASSWORD}@${DB_HOST}:${DB_PORT}/medusa-extender` + : `postgres://${DB_USER}@${DB_HOST}:${DB_PORT}/medusa-extender`; + +const plugins = [ + `medusa-fulfillment-manual`, + `medusa-payment-manual`, +]; + +module.exports = { + projectConfig: { + jwtSecret: 'supersecret', + cookieSecret: 'supersecret', + + database_url: DB_URL, + database_type: 'postgres', + }, + plugins +}; diff --git a/integration-tests/package.json b/integration-tests/package.json new file mode 100644 index 00000000..4855ce50 --- /dev/null +++ b/integration-tests/package.json @@ -0,0 +1,61 @@ +{ + "name": "integration-tests", + "version": "1.0.0", + "description": "", + "private": true, + "author": "adrien2p ", + "homepage": "https://github.com/adrien2p", + "license": "MIT", + "engines": { + "node": ">=14.17.3" + }, + "scripts": { + "prepare": "cd .. && npm pack --pack-destination integration-tests && cd - && PACKAGE_NAME=$(cat ../package.json | grep version | head -1 | awk -F: '{ print \"medusa-extender-\", $2, \".tgz\" }' | sed 's/[ \",]//g') && npm i ${PACKAGE_NAME} && rm -f ${PACKAGE_NAME}", + "test:integration": "NODE_ENV=development jest --runInBand --detectOpenHandles --forceExit --verbose" + }, + "dependencies": { + "@medusajs/medusa": "^1.3.0", + "awilix": "^6.1.0", + "bcrypt": "^5.0.1", + "class-transformer": "^0.5.1", + "class-validator": "^0.13.2", + "dotenv": "^12.0.4", + "express": "^4.17.1", + "jsonwebtoken": "^8.5.1", + "lodash": "^4.17.21", + "medusa-core-utils": "^1.1.31", + "medusa-extender": "file:medusa-extender-1.6.5.tgz", + "medusa-fulfillment-manual": "^1.1.30", + "medusa-interfaces": "^1.1.34", + "medusa-payment-manual": "^1.0.12", + "medusa-payment-stripe": "^1.1.34", + "mongoose": "^6.1.1", + "pg": "^8.7.1", + "pg-hstore": "^2.3.4", + "portfinder": "^1.0.28", + "prom-client": "^12.0.0", + "reflect-metadata": "^0.1.13", + "swagger-parser": "^10.0.3", + "swagger-stats": "^0.99.2", + "typeorm": "^0.2.41" + }, + "devDependencies": { + "@golevelup/ts-jest": "^0.3.2", + "@types/bcrypt": "^5.0.0", + "@types/express": "^4.17.13", + "@types/jest": "^27.0.3", + "@types/jsonwebtoken": "^8.5.6", + "@types/node": "^16.11.12", + "eslint": "^8.3.0", + "eslint-config-prettier": "^8.3.0", + "eslint-plugin-prettier": "^4.0.0", + "jest": "^27.3.1", + "pg-god": "^1.0.11", + "prettier": "^2.5.0", + "ts-jest": "^27.0.7", + "ts-loader": "^9.2.6", + "ts-node": "^10.4.0", + "tsconfig-paths": "^3.12.0", + "typescript": "^4.5.2" + } +} diff --git a/integration-tests/tests/fixtures/components.ts b/integration-tests/tests/fixtures/components.ts new file mode 100644 index 00000000..f8b51224 --- /dev/null +++ b/integration-tests/tests/fixtures/components.ts @@ -0,0 +1,19 @@ +import { Module, Service } from "medusa-extender"; +import { CartService as MedusaCartService } from '@medusajs/medusa'; + +@Service() +export class TestService { + static resolutionKey = "testService"; +} + +@Service({ override: MedusaCartService }) +export class CartService extends MedusaCartService { + static resolutionKey = "cartService"; + + customMethod = jest.fn(); +} + +@Module({ + imports: [TestService, CartService] +}) +export class TestModule {} \ No newline at end of file diff --git a/integration-tests/tests/integration.spec.ts b/integration-tests/tests/integration.spec.ts new file mode 100644 index 00000000..baef0ec6 --- /dev/null +++ b/integration-tests/tests/integration.spec.ts @@ -0,0 +1,94 @@ +import { resolve as pathResolve } from 'path'; +import express, { Express } from 'express'; +import portfinder from 'portfinder'; +import { AwilixContainer } from 'awilix'; +import { Medusa, Type } from 'medusa-extender'; +import { CartService as MedusaCartService } from '@medusajs/medusa'; +import { Server } from 'http'; +import { createDatabase, dropDatabase } from 'pg-god'; +import { CartService, TestModule, TestService } from './fixtures/components'; +import { execSync } from 'child_process'; + +const isCI = !!process.env.IS_CI; + +type Context = { app: Express; appListener: Server; port: number; container: AwilixContainer }; + +async function setupDb(): Promise { + if (!isCI) { + await dropDatabase({ databaseName: 'medusa-extender' }).catch(() => void 0); + await createDatabase({ databaseName: 'medusa-extender' }); + } + execSync('node_modules/.bin/medusa migrations run'); +} + +async function teardown(context: Context): Promise { + try { + await new Promise((resolve, reject) => + context.appListener.close((err) => (err ? reject(err) : resolve(void 0))) + ); + if (!isCI) { + await dropDatabase({ databaseName: 'medusa-extender' }); + } + } catch (e) {} +} + +async function loadServer(modules: Type[]): Promise { + return await new Promise((resolve, reject) => { + portfinder.getPort(async (err: unknown, port: number) => { + if (err) reject(err); + + const app = express(); + const container = await new Medusa(pathResolve(__dirname, '..'), app).load(modules); + + const appListener = app.listen(port); + + resolve({ + app, + appListener, + port, + container, + }); + }); + }); +} + +describe('Medusa-extender', () => { + let context!: Context; + + beforeAll(async () => { + await setupDb(); + context = await loadServer([TestModule]); + }); + + afterAll(async () => { + await teardown(context); + }); + + it('validate that the context is properly loaded', () => { + expect(context.app).toBeTruthy(); + expect(context.appListener).toBeTruthy(); + expect(context.port).toBeTruthy(); + expect(context.container).toBeTruthy(); + }); + + describe('services loader', () => { + it('should load service components', () => { + const testService: TestService = context.container.resolve(TestService.resolutionKey); + expect(testService).toBeTruthy(); + expect(testService).toBeInstanceOf(TestService); + }); + + it('should load overridden service components', () => { + const cartService: CartService = context.container.resolve(CartService.resolutionKey); + expect(cartService).toBeTruthy(); + expect(cartService).toBeInstanceOf(CartService); + expect(cartService).toBeInstanceOf(MedusaCartService); + + expect(cartService.customMethod).toBeTruthy(); + + cartService.customMethod(); + + expect(cartService.customMethod).toHaveBeenCalled(); + }); + }); +}); diff --git a/integration-tests/tsconfig.json b/integration-tests/tsconfig.json new file mode 100644 index 00000000..c806be7c --- /dev/null +++ b/integration-tests/tsconfig.json @@ -0,0 +1,22 @@ +{ + "compilerOptions": { + "module": "CommonJS", + "declaration": true, + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "allowSyntheticDefaultImports": true, + "moduleResolution": "node", + "target": "es2017", + "sourceMap": true, + "skipLibCheck": true, + "allowJs": true, + "outDir": "dist", + "esModuleInterop": true + }, + "include": [ + "tests" + ], + "exclude": [ + "node_modules" + ] +} \ No newline at end of file diff --git a/package.json b/package.json index cccc9a4a..194c79fc 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "build:doc": "npm run build:readme && rm -rf docs && ./node_modules/.bin/typedoc && cp .github/docs/* docs/ && cp documentation/_README_BUILT.md docs/README.md", "serve:doc": "./node_modules/.bin/docsify serve docs", "test": "NODE_ENV=test ./node_modules/.bin/jest -i --collect-coverage && npm run coverage:badges", + "test:integration": "cd integration-tests && npm run prepare && npm run test:integration", "test:local": "NODE_ENV=test ./node_modules/.bin/jest --maxWorkers=75% --collect-coverage && npm run coverage:badges", "coverage:badges": "./node_modules/.bin/jest-coverage-badges --output coverage-badges", "release": "standard-version", diff --git a/starters/plugin-module/src/modules/user/attachUserSubscribers.middleware.ts b/starters/plugin-module/src/modules/user/attachUserSubscribers.middleware.ts index 9201ab3d..d1a2ede3 100644 --- a/starters/plugin-module/src/modules/user/attachUserSubscribers.middleware.ts +++ b/starters/plugin-module/src/modules/user/attachUserSubscribers.middleware.ts @@ -1,9 +1,5 @@ import { NextFunction, Request, Response } from 'express'; -import { - MEDUSA_RESOLVER_KEYS, - MedusaAuthenticatedRequest, - Middleware, -} from 'medusa-extender'; +import { MEDUSA_RESOLVER_KEYS, MedusaAuthenticatedRequest, Middleware } from 'medusa-extender'; import { Connection } from 'typeorm'; import UserSubscriber from './user.subscriber'; diff --git a/starters/server/medusa-config.js b/starters/server/medusa-config.js index 83e7397a..3e7f9c66 100644 --- a/starters/server/medusa-config.js +++ b/starters/server/medusa-config.js @@ -1,4 +1,4 @@ -import * as dotenv from 'dotenv'; +const dotenv = require('dotenv'); let ENV_FILE_NAME = ''; switch (process.env.NODE_ENV) { diff --git a/starters/server/src/modules/user/attachUserSubscribers.middleware.ts b/starters/server/src/modules/user/attachUserSubscribers.middleware.ts index 9201ab3d..d1a2ede3 100644 --- a/starters/server/src/modules/user/attachUserSubscribers.middleware.ts +++ b/starters/server/src/modules/user/attachUserSubscribers.middleware.ts @@ -1,9 +1,5 @@ import { NextFunction, Request, Response } from 'express'; -import { - MEDUSA_RESOLVER_KEYS, - MedusaAuthenticatedRequest, - Middleware, -} from 'medusa-extender'; +import { MEDUSA_RESOLVER_KEYS, MedusaAuthenticatedRequest, Middleware } from 'medusa-extender'; import { Connection } from 'typeorm'; import UserSubscriber from './user.subscriber';