diff --git a/.github/workflows/issues-jira.yml b/.github/workflows/issues-jira.yml new file mode 100644 index 00000000..7bf04694 --- /dev/null +++ b/.github/workflows/issues-jira.yml @@ -0,0 +1,31 @@ +name: Create Jira Ticket for Github Issue + +on: + issues: + types: [opened] + +jobs: + issue-jira: + runs-on: ubuntu-latest + steps: + + - name: Login to Jira + uses: atlassian/gajira-login@master + env: + JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} + JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} + JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} + + - name: Create Jira Issue + id: create_jira + uses: atlassian/gajira-create@master + with: + project: ${{ secrets.JIRA_PROJECT }} + issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} + summary: Github | Issue | ${{ github.event.repository.name }} | ${{ github.event.issue.title }} + description: | + *GitHub Issue:* ${{ github.event.issue.html_url }} + + *Description:* + ${{ github.event.issue.body }} + fields: "${{ secrets.ISSUES_JIRA_FIELDS }}" \ No newline at end of file diff --git a/.github/workflows/jira.yml b/.github/workflows/jira.yml deleted file mode 100644 index 250abc76..00000000 --- a/.github/workflows/jira.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Create JIRA ISSUE -on: - pull_request: - types: [opened] -jobs: - security-jira: - if: ${{ github.actor == 'dependabot[bot]' || github.actor == 'snyk-bot' || contains(github.event.pull_request.head.ref, 'snyk-fix-') || contains(github.event.pull_request.head.ref, 'snyk-upgrade-')}} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Login into JIRA - uses: atlassian/gajira-login@master - env: - JIRA_BASE_URL: ${{ secrets.JIRA_BASE_URL }} - JIRA_USER_EMAIL: ${{ secrets.JIRA_USER_EMAIL }} - JIRA_API_TOKEN: ${{ secrets.JIRA_API_TOKEN }} - - name: Create a JIRA Issue - id: create - uses: atlassian/gajira-create@master - with: - project: ${{ secrets.JIRA_PROJECT }} - issuetype: ${{ secrets.JIRA_ISSUE_TYPE }} - summary: | - Snyk | Vulnerability | ${{ github.event.repository.name }} | ${{ github.event.pull_request.title }} - description: | - PR: ${{ github.event.pull_request.html_url }} - - fields: "${{ secrets.JIRA_FIELDS }}" - - name: Transition issue - uses: atlassian/gajira-transition@v3 - with: - issue: ${{ steps.create.outputs.issue }} - transition: ${{ secrets.JIRA_TRANSITION }} diff --git a/.github/workflows/policy-scan.yml b/.github/workflows/policy-scan.yml new file mode 100644 index 00000000..ff259231 --- /dev/null +++ b/.github/workflows/policy-scan.yml @@ -0,0 +1,46 @@ +name: Checks the security policy and configurations +on: + pull_request: + types: [opened, synchronize, reopened] +jobs: + security-policy: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for SECURITY.md policy file + run: | + if ! [[ -f "SECURITY.md" || -f ".github/SECURITY.md" ]]; then exit 1; fi + security-license: + if: github.event.repository.visibility == 'public' + runs-on: ubuntu-latest + defaults: + run: + shell: bash + steps: + - uses: actions/checkout@master + - name: Checks for License file + run: | + expected_license_files=("LICENSE" "LICENSE.txt" "LICENSE.md" "License.txt") + license_file_found=false + current_year=$(date +"%Y") + + for license_file in "${expected_license_files[@]}"; do + if [ -f "$license_file" ]; then + license_file_found=true + # check the license file for the current year, if not exists, exit with error + if ! grep -q "$current_year" "$license_file"; then + echo "License file $license_file does not contain the current year." + exit 2 + fi + break + fi + done + + if [ "$license_file_found" = false ]; then + echo "No license file found. Please add a license file to the repository." + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/sast-scan.yml b/.github/workflows/sast-scan.yml deleted file mode 100644 index 3b9521a5..00000000 --- a/.github/workflows/sast-scan.yml +++ /dev/null @@ -1,11 +0,0 @@ -name: SAST Scan -on: - pull_request: - types: [opened, synchronize, reopened] -jobs: - security-sast: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Semgrep Scan - run: docker run -v /var/run/docker.sock:/var/run/docker.sock -v "${PWD}:/src" returntocorp/semgrep semgrep scan --config auto \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 683b6cfa..d1b89af9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,26 @@ ## Change log + +### Version: 3.25.3 +#### Date: April-21-2025 +##### Fix: + - Handle the sanity tests when ENVs are not provided. + +### Version: 3.25.2 +#### Date: April-02-2025 +##### Fix: + - allow number, string, object, boolean, and RegExp as valid query parameters in sync method + +### Version: 3.25.1 +#### Date: April-01-2025 +##### Fix: + - Update dependencies + - Update slack notification + +### Version: 3.25.0 +#### Date: March-10-2025 +##### Fix: + - Added GCP-EU support + ### Version: 3.24.3 #### Date: March-03-2025 ##### Fix: diff --git a/README.md b/README.md index 5dffec71..3471eda5 100755 --- a/README.md +++ b/README.md @@ -19,11 +19,11 @@ For browsers, we recommend to download the library via npm or yarn to ensure 100 If you'd like to use a standalone built file you can use the following script tag or download it from [jsDelivr](https://www.jsdelivr.com/package/npm/contentstack), under the `dist` directory: ```html - + ``` You can also specify a specific version number. ```html - + ``` To initialize the SDK, you will need to specify the API Key, Delivery Token, and Environment Name of your stack. diff --git a/index.d.ts b/index.d.ts index a829b303..b4df3b24 100644 --- a/index.d.ts +++ b/index.d.ts @@ -25,6 +25,7 @@ export enum Region { AZURE_NA = "azure-na", AZURE_EU = "azure-eu", GCP_NA = "gcp-na", + GCP_EU = "gcp-eu" } //Enum for Contentstack CachePolicy diff --git a/jest.js.config.js b/jest.js.config.js new file mode 100644 index 00000000..6bfd5308 --- /dev/null +++ b/jest.js.config.js @@ -0,0 +1,20 @@ +module.exports = { + testEnvironment: "node", + testMatch: ["**/test/**/*.js"], + testPathIgnorePatterns: [ + "/node_modules/", + "/test/index.js", + "/test/config.js", + "/test/sync_config.js", + "/test/.*/utils.js", + ], + reporters: ["default", ["jest-html-reporters", + { + "filename": "tap-html.html", + "expand": true, + "inlineSource": true, + "includeFailureMsg": true, // Includes error messages in JSON + "includeConsoleLog": true + } + ]], +}; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 2357221b..a0a94e0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,18 +1,18 @@ { "name": "contentstack", - "version": "3.24.3", + "version": "3.25.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "contentstack", - "version": "3.24.3", + "version": "3.25.3", "license": "MIT", "dependencies": { - "@contentstack/utils": "^1.3.15", - "@fetch-mock/jest": "^0.2.10", + "@contentstack/utils": "^1.3.20", + "@fetch-mock/jest": "^0.2.15", "es6-promise": "^4.2.8", - "fetch-mock": "^12.2.0", + "fetch-mock": "^12.5.2", "localStorage": "1.0.4", "qs": "^6.14.0" }, @@ -69,14 +69,14 @@ } }, "node_modules/@asamuzakjp/css-color": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-2.8.3.tgz", - "integrity": "sha512-GIc76d9UI1hCvOATjZPyHFmE5qhRccp3/zGfMPapK3jBi+yocEzp6BBB0UnfRYP9NP4FANqUZYb0hnfs3TM3hw==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.1.2.tgz", + "integrity": "sha512-nwgc7jPn3LpZ4JWsoHtuwBsad1qSSLDDX634DdG0PBJofIuIEtSWk4KkRmuXyu178tjuHAbwiMNNzwqIyLYxZw==", "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.1", - "@csstools/css-color-parser": "^3.0.7", + "@csstools/css-calc": "^2.1.2", + "@csstools/css-color-parser": "^3.0.8", "@csstools/css-parser-algorithms": "^3.0.4", "@csstools/css-tokenizer": "^3.0.3", "lru-cache": "^10.4.3" @@ -104,30 +104,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.5.tgz", - "integrity": "sha512-XvcZi1KWf88RVbF9wn8MN6tYFloU5qX8KjuF3E1PVBmJ9eypXfs4GRiJwLuTZL0iSnJUKn1BFPa5BPZZJyFzPg==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.26.8.tgz", + "integrity": "sha512-oH5UPLMWR3L2wEFLnFJ1TZXqHufiTKAiLfqw5zkhS4dKXLJ10yVztfil/twG8EDTA4F/tvVNw9nOl4ZMslB8rQ==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.7.tgz", - "integrity": "sha512-SRijHmF0PSPgLIBYlWnG0hyeJLwXE2CgpsXaMOrtt2yp9/86ALw6oUlj9KYuZ0JN07T4eBMVIW4li/9S1j2BGA==", + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", + "@babel/generator": "^7.26.10", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-module-transforms": "^7.26.0", - "@babel/helpers": "^7.26.7", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.26.7", - "@babel/types": "^7.26.7", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -143,13 +143,13 @@ } }, "node_modules/@babel/generator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.5.tgz", - "integrity": "sha512-2caSP6fN9I7HOe6nqhtft7V4g7/V/gfDsC3Ag4W7kEzzvRGKqiv0pu0HogPiZ3KaVSoNDhUws6IJjDjpfmYIXw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.27.0.tgz", + "integrity": "sha512-VybsKvpiN1gU1sdMZIp7FcqphVVKEwcuj02x73uvcHE0PTihx1nlBcowYWhDwjpoAXRv43+gDzyggGnn1XZhVw==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.26.5", - "@babel/types": "^7.26.5", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0", "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^3.0.2" @@ -172,12 +172,12 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.26.5.tgz", - "integrity": "sha512-IXuyn5EkouFJscIDuFF5EsiSolseme1s0CZB+QxVugqJLYmKdxI1VfIBOst0SUu4rnk2Z7kqTwmoO1lp3HIfnA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.0.tgz", + "integrity": "sha512-LVk7fbXml0H2xH34dFzKQ7TDZ2G4/rVTOrq9V+icbbadjbVxxeFeDsNHv2SrZeWoA+6ZiTyWYWtScEIW07EAcA==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/compat-data": "^7.26.8", "@babel/helper-validator-option": "^7.25.9", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", @@ -188,18 +188,18 @@ } }, "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", - "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.0.tgz", + "integrity": "sha512-vSGCvMecvFCd/BdpGlhpXYNhhC4ccxyvQWpbGL4CWbvfEoLFWUZuSuf7s9Aw70flgQF+6vptvgK2IfOnKlRmBg==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-member-expression-to-functions": "^7.25.9", "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-replace-supers": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.25.9", + "@babel/traverse": "^7.27.0", "semver": "^6.3.1" }, "engines": { @@ -210,9 +210,9 @@ } }, "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", - "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.0.tgz", + "integrity": "sha512-fO8l08T76v48BhpNRW/nQ0MxfnSdoSKUJBMjubOAYffsVuGG5qOfMq7N6Es7UJvi7Y8goXXo07EfcHZXDPuELQ==", "dev": true, "license": "MIT", "dependencies": { @@ -228,9 +228,9 @@ } }, "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", - "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.4.tgz", + "integrity": "sha512-jljfR1rGnXXNWnmQg2K3+bvhkxB51Rl32QRaOTuwwjviGrHzIbSc8+x9CpraDtbT7mfyjXObULP4w/adunNwAw==", "dev": true, "license": "MIT", "dependencies": { @@ -403,25 +403,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.26.7.tgz", - "integrity": "sha512-8NHiL98vsi0mbPQmYAGWwfcFaOy4j2HY49fXJCfuDcdE7fMIsH9a7GdaeXpIBsbT7307WU8KCMp5pUVDNL4f9A==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.0.tgz", + "integrity": "sha512-U5eyP/CTFPuNE3qk+WZMxFkp/4zUzdceQlfzf7DdGdhp+Fezd7HD+i8Y24ZuTMKX3wQBld449jijbGq6OdGNQg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7" + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.26.7.tgz", - "integrity": "sha512-kEvgGGgEjRUutvdVvZhbn/BxVt+5VSpwXz1j3WYXQbXDo8KzFOPNG2GQbdAiNq8g6wn1yKk7C/qrke03a84V+w==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.27.0.tgz", + "integrity": "sha512-iaepho73/2Pz7w2eMS0Q5f83+0RKI7i4xmiYeBmDzfRVbQtTOG7Ts0S4HzJVsTMGI9keU8rNfuZr8DKfSt7Yyg==", "license": "MIT", "dependencies": { - "@babel/types": "^7.26.7" + "@babel/types": "^7.27.0" }, "bin": { "parser": "bin/babel-parser.js" @@ -799,15 +799,15 @@ } }, "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", - "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/traverse": "^7.26.8" }, "engines": { "node": ">=6.9.0" @@ -851,13 +851,13 @@ } }, "node_modules/@babel/plugin-transform-block-scoping": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", - "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.27.0.tgz", + "integrity": "sha512-u1jGphZ8uDI2Pj/HJj6YQ6XQLZCNjOlprjxB5SVz6rq2T6SwAR+CdrWK0CP7F+9rDVMXdB0+r6Am5G5aobOjAQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1053,13 +1053,13 @@ } }, "node_modules/@babel/plugin-transform-for-of": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", - "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.26.9.tgz", + "integrity": "sha512-Hry8AusVm8LW5BVFgiyUReuoGzPUpdHQQqJY5bZnbbf+ngOHWuCuYFKw/BqaaWlvEUrF91HMhDtEaI1hZzNbLg==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { @@ -1422,13 +1422,13 @@ } }, "node_modules/@babel/plugin-transform-regenerator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", - "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.27.0.tgz", + "integrity": "sha512-LX/vCajUJQDqE7Aum/ELUMZAY19+cDpghxrnyt5I1tV6X5PyC86AOoWXWFYFeIvauyeSA6/ktn4tQVn/3ZifsA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", "regenerator-transform": "^0.15.2" }, "engines": { @@ -1521,13 +1521,13 @@ } }, "node_modules/@babel/plugin-transform-template-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", - "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.26.8.tgz", + "integrity": "sha512-OmGDL5/J0CJPJZTHZbi2XpO0tyT2Ia7fzpW5GURwdtp2X3fMmN8au/ej6peC/T33/+CRiIpA8Krse8hFGVmT5Q==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1537,9 +1537,9 @@ } }, "node_modules/@babel/plugin-transform-typeof-symbol": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.26.7.tgz", - "integrity": "sha512-jfoTXXZTgGg36BmhqT3cAYK5qkmqvJpvNrPhaK/52Vgjhw4Rq29s9UqpWWV0D6yuRmgiFH/BUVlkl96zJWqnaw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.0.tgz", + "integrity": "sha512-+LLkxA9rKJpNoGsbLnAgOCdESl73vwYn+V6b+5wHbrE7OGKVDPHIQvbFSzqE6rwqaCw2RE+zdJrlLkcf8YOA0w==", "dev": true, "license": "MIT", "dependencies": { @@ -1620,13 +1620,13 @@ } }, "node_modules/@babel/preset-env": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.7.tgz", - "integrity": "sha512-Ycg2tnXwixaXOVb29rana8HNPgLVBof8qqtNQ9LE22IoyZboQbGSxI6ZySMdW3K5nAe6gu35IaJefUJflhUFTQ==", + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.26.5", + "@babel/compat-data": "^7.26.8", "@babel/helper-compilation-targets": "^7.26.5", "@babel/helper-plugin-utils": "^7.26.5", "@babel/helper-validator-option": "^7.25.9", @@ -1640,7 +1640,7 @@ "@babel/plugin-syntax-import-attributes": "^7.26.0", "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", "@babel/plugin-transform-async-to-generator": "^7.25.9", "@babel/plugin-transform-block-scoped-functions": "^7.26.5", "@babel/plugin-transform-block-scoping": "^7.25.9", @@ -1655,7 +1655,7 @@ "@babel/plugin-transform-dynamic-import": "^7.25.9", "@babel/plugin-transform-exponentiation-operator": "^7.26.3", "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", "@babel/plugin-transform-function-name": "^7.25.9", "@babel/plugin-transform-json-strings": "^7.25.9", "@babel/plugin-transform-literals": "^7.25.9", @@ -1683,7 +1683,7 @@ "@babel/plugin-transform-shorthand-properties": "^7.25.9", "@babel/plugin-transform-spread": "^7.25.9", "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", "@babel/plugin-transform-typeof-symbol": "^7.26.7", "@babel/plugin-transform-unicode-escapes": "^7.25.9", "@babel/plugin-transform-unicode-property-regex": "^7.25.9", @@ -1691,9 +1691,9 @@ "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", "@babel/preset-modules": "0.1.6-no-external-plugins", "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-corejs3": "^0.11.0", "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.38.1", + "core-js-compat": "^3.40.0", "semver": "^6.3.1" }, "engines": { @@ -1719,9 +1719,9 @@ } }, "node_modules/@babel/runtime": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.7.tgz", - "integrity": "sha512-AOPI3D+a8dXnja+iwsUqGRjr1BbZIe771sXdapOtYI531gSqpi92vXivKcq2asu/DFpdl1ceFAKZyRzK2PCVcQ==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz", + "integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==", "dev": true, "license": "MIT", "dependencies": { @@ -1732,30 +1732,30 @@ } }, "node_modules/@babel/template": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.25.9.tgz", - "integrity": "sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.0.tgz", + "integrity": "sha512-2ncevenBqXI6qRMukPlXwHKHchC7RyMuu4xv5JBXRfOGVcTy1mXCD12qrp7Jsoxll1EV3+9sE4GugBVRjT2jFA==", "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.25.9", - "@babel/parser": "^7.25.9", - "@babel/types": "^7.25.9" + "@babel/code-frame": "^7.26.2", + "@babel/parser": "^7.27.0", + "@babel/types": "^7.27.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.26.7.tgz", - "integrity": "sha512-1x1sgeyRLC3r5fQOM0/xtQKsYjyxmFjaOrLJNtZ81inNjyJHGIolTULPiSc/2qe1/qfpFLisLQYFnnZl7QoedA==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.27.0.tgz", + "integrity": "sha512-19lYZFzYVQkkHkl4Cy4WrAVcqBkgvV2YM2TU3xG6DIwO7O3ecbDPfW3yM3bjAGcqcQHi+CCtjMR3dIEHxsd6bA==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.26.2", - "@babel/generator": "^7.26.5", - "@babel/parser": "^7.26.7", - "@babel/template": "^7.25.9", - "@babel/types": "^7.26.7", + "@babel/generator": "^7.27.0", + "@babel/parser": "^7.27.0", + "@babel/template": "^7.27.0", + "@babel/types": "^7.27.0", "debug": "^4.3.1", "globals": "^11.1.0" }, @@ -1764,9 +1764,9 @@ } }, "node_modules/@babel/types": { - "version": "7.26.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.26.7.tgz", - "integrity": "sha512-t8kDRGrKXyp6+tjUh7hw2RLyclsW4TRoRvRHtSyAX9Bb5ldlFh+90YAYY6awRXrlB4G5G2izNeGySpATlFzmOg==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.27.0.tgz", + "integrity": "sha512-H45s8fVLYjbhFH62dIJ3WtmJ6RSPt/3DRO0ZcT2SUiYiQyz3BLVb9ADEnLl91m74aQPS3AzzeajZHYOalWe3bg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.25.9", @@ -1783,15 +1783,15 @@ "license": "MIT" }, "node_modules/@contentstack/utils": { - "version": "1.3.16", - "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.3.16.tgz", - "integrity": "sha512-HfVEwh7Da8xV4iZth/ci5bcOqszTx/U2mOzsWbyjHLeOfiU9U7uj6DefrrAPhNhL7JgCq/EpRd3vFtaxiEHBlA==", + "version": "1.3.20", + "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.3.20.tgz", + "integrity": "sha512-WXkFv5uKrAMs21NPCWe3+7KHYfagenS8rv1/yCDsZ+uV1FvKkzst+MiU1+hcaWHi0E6QaPpYDcxpiltUHo5TSA==", "license": "MIT" }, "node_modules/@csstools/color-helpers": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.1.tgz", - "integrity": "sha512-MKtmkA0BX87PKaO1NFRTFH+UnkgnmySQOvNxJubsadusqPEC2aJ9MOQiMceZJJ6oitUl/i0L6u0M1IrmAOmgBA==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/@csstools/color-helpers/-/color-helpers-5.0.2.tgz", + "integrity": "sha512-JqWH1vsgdGcw2RR6VliXXdA0/59LttzlU8UlRT/iUUsEeWfYq8I+K0yhihEUTTHLRm1EXvpsCx3083EU15ecsA==", "dev": true, "funding": [ { @@ -1809,9 +1809,9 @@ } }, "node_modules/@csstools/css-calc": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.1.tgz", - "integrity": "sha512-rL7kaUnTkL9K+Cvo2pnCieqNpTKgQzy5f+N+5Iuko9HAoasP+xgprVh7KN/MaJVvVL1l0EzQq2MoqBHKSrDrag==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@csstools/css-calc/-/css-calc-2.1.2.tgz", + "integrity": "sha512-TklMyb3uBB28b5uQdxjReG4L80NxAqgrECqLZFQbyLekwwlcDDS8r3f07DKqeo8C4926Br0gf/ZDe17Zv4wIuw==", "dev": true, "funding": [ { @@ -1833,9 +1833,9 @@ } }, "node_modules/@csstools/css-color-parser": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.7.tgz", - "integrity": "sha512-nkMp2mTICw32uE5NN+EsJ4f5N+IGFeCFu4bGpiKgb2Pq/7J/MpyLBeQ5ry4KKtRFZaYs6sTmcMYrSRIyj5DFKA==", + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/@csstools/css-color-parser/-/css-color-parser-3.0.8.tgz", + "integrity": "sha512-pdwotQjCCnRPuNi06jFuP68cykU1f3ZWExLe/8MQ1LOs8Xq+fTkYgd+2V8mWUWMrOn9iS2HftPVaMZDaXzGbhQ==", "dev": true, "funding": [ { @@ -1849,8 +1849,8 @@ ], "license": "MIT", "dependencies": { - "@csstools/color-helpers": "^5.0.1", - "@csstools/css-calc": "^2.1.1" + "@csstools/color-helpers": "^5.0.2", + "@csstools/css-calc": "^2.1.2" }, "engines": { "node": ">=18" @@ -1914,12 +1914,12 @@ } }, "node_modules/@fetch-mock/jest": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@fetch-mock/jest/-/jest-0.2.10.tgz", - "integrity": "sha512-nBZUUrYhuCzzmCx0jmGTZOfENf7IhmyYG89WMquHlCkqYSXBJT5PldFg+P107QZcShQPUmqxyLzGHdmsL7mmJw==", + "version": "0.2.15", + "resolved": "https://registry.npmjs.org/@fetch-mock/jest/-/jest-0.2.15.tgz", + "integrity": "sha512-cudDyqZr/mzA/AsXzowx3Il5C7//lOaBn3CW/+gzitGRk621ZPSdlZYbaq3kwxji5vwUaaFQE0saKBLHi2K6fQ==", "license": "MIT", "dependencies": { - "fetch-mock": "^12.3.0" + "fetch-mock": "^12.5.2" }, "engines": { "node": ">=18.11.0" @@ -2350,13 +2350,13 @@ } }, "node_modules/@ljharb/through": { - "version": "2.3.13", - "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.13.tgz", - "integrity": "sha512-/gKJun8NNiWGZJkGzI/Ragc53cOdcLNdzjLaIa+GEjguQs0ulsurx8WN0jijdK9yPqDvziX995sMRLyLt1uZMQ==", + "version": "2.3.14", + "resolved": "https://registry.npmjs.org/@ljharb/through/-/through-2.3.14.tgz", + "integrity": "sha512-ajBvlKpWucBB17FuQYUShqpqy8GRgYEpJW0vWJbUu1CV9lWyrDCapy0lScU8T8Z6qn49sSwJB3+M+evYIdGg+A==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7" + "call-bind": "^1.0.8" }, "engines": { "node": ">= 0.4" @@ -2394,9 +2394,9 @@ } }, "node_modules/@slack/bolt": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/@slack/bolt/-/bolt-4.2.0.tgz", - "integrity": "sha512-KQGUkC37t6DUR+FVglHmcUrMpdCLbY9wpZXfjW6CUNmQnINits+EeOrVN/5xPcISKJcBIhqgrarLpwU9tpESTw==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@slack/bolt/-/bolt-4.2.1.tgz", + "integrity": "sha512-O+c7i5iZKlxt6ltJAu2BclEoyWuAVkcpir1F3HWCHTez8Pjz0GxwdBzNHR5HDXvOdBT7En1BU0T2L6Ldv++GSg==", "dev": true, "license": "MIT", "dependencies": { @@ -2414,6 +2414,9 @@ "engines": { "node": ">=18", "npm": ">=8.6.0" + }, + "peerDependencies": { + "@types/express": "^5.0.0" } }, "node_modules/@slack/logger": { @@ -2431,14 +2434,14 @@ } }, "node_modules/@slack/oauth": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@slack/oauth/-/oauth-3.0.2.tgz", - "integrity": "sha512-MdPS8AP9n3u/hBeqRFu+waArJLD/q+wOSZ48ktMTwxQLc6HJyaWPf8soqAyS/b0D6IlvI5TxAdyRyyv3wQ5IVw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@slack/oauth/-/oauth-3.0.3.tgz", + "integrity": "sha512-N3pLJPacZ57bqmD1HzHDmHe/CNsL9pESZXRw7pfv6QXJVRgufPIW84aRpAez2Xb0616RpGBYZW5dZH0Nbskwyg==", "dev": true, "license": "MIT", "dependencies": { "@slack/logger": "^4", - "@slack/web-api": "^7.8.0", + "@slack/web-api": "^7.9.1", "@types/jsonwebtoken": "^9", "@types/node": ">=18", "jsonwebtoken": "^9", @@ -2450,14 +2453,14 @@ } }, "node_modules/@slack/socket-mode": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@slack/socket-mode/-/socket-mode-2.0.3.tgz", - "integrity": "sha512-aY1AhQd3HAgxLYC2Mz47dXtW6asjyYp8bJ24MWalg+qFWPaXj8VBYi+5w3rfGqBW5IxlIhs3vJTEQtIBrqQf5A==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@slack/socket-mode/-/socket-mode-2.0.4.tgz", + "integrity": "sha512-PB2fO4TSv47TXJ6WlKY7BeVNdcHcpPOxZsztGyG7isWXp69MVj+xAzQ3KSZ8aVTgV59f8xFJPXSHipn1x2Z5IQ==", "dev": true, "license": "MIT", "dependencies": { "@slack/logger": "^4", - "@slack/web-api": "^7.8.0", + "@slack/web-api": "^7.9.1", "@types/node": ">=18", "@types/ws": "^8", "eventemitter3": "^5", @@ -2480,9 +2483,9 @@ } }, "node_modules/@slack/web-api": { - "version": "7.8.0", - "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.8.0.tgz", - "integrity": "sha512-d4SdG+6UmGdzWw38a4sN3lF/nTEzsDxhzU13wm10ejOpPehtmRoqBKnPztQUfFiWbNvSb4czkWYJD4kt+5+Fuw==", + "version": "7.9.1", + "resolved": "https://registry.npmjs.org/@slack/web-api/-/web-api-7.9.1.tgz", + "integrity": "sha512-qMcb1oWw3Y/KlUIVJhkI8+NcQXq1lNymwf+ewk93ggZsGd6iuz9ObQsOEbvlqlx1J+wd8DmIm3DORGKs0fcKdg==", "dev": true, "license": "MIT", "dependencies": { @@ -2490,7 +2493,7 @@ "@slack/types": "^2.9.0", "@types/node": ">=18.0.0", "@types/retry": "0.12.0", - "axios": "^1.7.8", + "axios": "^1.8.3", "eventemitter3": "^5.0.1", "form-data": "^4.0.0", "is-electron": "2.2.2", @@ -2518,9 +2521,9 @@ } }, "node_modules/@types/babel__generator": { - "version": "7.6.8", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", - "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "version": "7.27.0", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", + "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "license": "MIT", "dependencies": { "@babel/types": "^7.0.0" @@ -2537,14 +2540,37 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", - "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.7.tgz", + "integrity": "sha512-dkO5fhS7+/oos4ciWxyEyjWe48zmG6wbCheo/G2ZnHx4fs3EU6YC6UM8rk56gAjNJ9P3MTH2jo5jb92/K6wbng==", "license": "MIT", "dependencies": { "@babel/types": "^7.20.7" } }, + "node_modules/@types/body-parser": { + "version": "1.19.5", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", + "integrity": "sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/eslint": { "version": "9.6.1", "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", @@ -2568,12 +2594,39 @@ } }, "node_modules/@types/estree": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", - "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", + "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==", "dev": true, "license": "MIT" }, + "node_modules/@types/express": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/express/-/express-5.0.1.tgz", + "integrity": "sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^5.0.0", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-5.0.6.tgz", + "integrity": "sha512-3xhRnjJPkULekpSzgtoNYYcTWgEZkp4myc+Saevii5JPnHNvHMRlBSHDbs7Bh1iPPoVTERHEZXyhyLbMEsExsA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, "node_modules/@types/glob": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", @@ -2600,6 +2653,14 @@ "@types/node": "*" } }, + "node_modules/@types/http-errors": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.4.tgz", + "integrity": "sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -2643,9 +2704,9 @@ "license": "MIT" }, "node_modules/@types/jsonwebtoken": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.8.tgz", - "integrity": "sha512-7fx54m60nLFUVYlxAB1xpe9CBWX2vSrk50Y6ogRJ1v5xxtba7qXTg5BgYDN5dq+yuQQ9HaVlHJyAAt1/mxryFg==", + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz", + "integrity": "sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2678,6 +2739,14 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", @@ -2693,14 +2762,30 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.12.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.12.0.tgz", - "integrity": "sha512-Fll2FZ1riMjNmlmJOdAyY5pUbkftXslB5DgEzlIuNaiWhXd00FhWxVC/r4yV/4wBb9JfImTu+jiSvXTkJ7F/gA==", + "version": "22.14.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", + "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", "license": "MIT", "dependencies": { - "undici-types": "~6.20.0" + "undici-types": "~6.21.0" } }, + "node_modules/@types/qs": { + "version": "6.9.18", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.18.tgz", + "integrity": "sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -2708,6 +2793,31 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/send": { + "version": "0.17.4", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.4.tgz", + "integrity": "sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.7", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.7.tgz", + "integrity": "sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2715,9 +2825,9 @@ "license": "MIT" }, "node_modules/@types/ws": { - "version": "8.5.14", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.14.tgz", - "integrity": "sha512-bd/YFLW+URhBzMXurx7lWByOu+xzU9+kb3RboOteXYDfW+tr+JZa99OyNmPINEGB/ahzKrEuc8rcv4gnpJmxTw==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", "dev": true, "license": "MIT", "dependencies": { @@ -3134,13 +3244,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-flatten": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-3.0.0.tgz", - "integrity": "sha512-zPMVc3ZYlGLNk4mpK1NzP2wg0ml9t7fUgDsayR5Y5rSzxQilzR9FGu/EH2jQOcKSAeAfWeylyW8juy3OkWRvNA==", - "dev": true, - "license": "MIT" - }, "node_modules/array-union": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", @@ -3237,9 +3340,9 @@ } }, "node_modules/axios": { - "version": "1.7.9", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", - "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "version": "1.8.4", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", + "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", "dev": true, "license": "MIT", "dependencies": { @@ -3335,14 +3438,14 @@ } }, "node_modules/babel-plugin-polyfill-corejs2": { - "version": "0.4.12", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.12.tgz", - "integrity": "sha512-CPWT6BwvhrTO2d8QVorhTCQw9Y43zOu7G9HigcfxvepOU6b8o3tcWad6oVgZIsZCTt42FFv97aA7ZJsbM4+8og==", + "version": "0.4.13", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.13.tgz", + "integrity": "sha512-3sX/eOms8kd3q2KZ6DAhKPc0dgm525Gqq5NtWKZ7QYYZEv57OQ54KtblzJzH1lQF/eQxO8KjWGIK9IPUJNus5g==", "dev": true, "license": "MIT", "dependencies": { "@babel/compat-data": "^7.22.6", - "@babel/helper-define-polyfill-provider": "^0.6.3", + "@babel/helper-define-polyfill-provider": "^0.6.4", "semver": "^6.3.1" }, "peerDependencies": { @@ -3350,27 +3453,27 @@ } }, "node_modules/babel-plugin-polyfill-corejs3": { - "version": "0.10.6", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz", - "integrity": "sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA==", + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.2", - "core-js-compat": "^3.38.0" + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, "node_modules/babel-plugin-polyfill-regenerator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.3.tgz", - "integrity": "sha512-LiWSbl4CRSIa5x/JAU6jZiG9eit9w6mz+yVMFwDE83LAWvt0AfGBoZ7HS/mkhrKuh2ZlzfVZYKoLjXdqw6Yt7Q==", + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.4.tgz", + "integrity": "sha512-7gD3pRadPrbjhjLyxebmx/WrFYcuSjZ0XbdUujQMZ/fcE9oeewk2U/7PCvez84UeuK3oSjmPZ0Ch0dlupQvGzw==", "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-define-polyfill-provider": "^0.6.3" + "@babel/helper-define-polyfill-provider": "^0.6.4" }, "peerDependencies": { "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" @@ -3452,120 +3555,26 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.0.2.tgz", - "integrity": "sha512-SNMk0OONlQ01uk8EPeiBvTW7W4ovpL5b1O3t1sjpPgfxOQ6BqQJ6XjxinDPR79Z6HdcD5zBBwr5ssiTlgdNztQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz", + "integrity": "sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg==", "dev": true, "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "content-type": "~1.0.5", - "debug": "3.1.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.5.2", - "on-finished": "2.4.1", - "qs": "6.13.0", + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.0", + "http-errors": "^2.0.0", + "iconv-lite": "^0.6.3", + "on-finished": "^2.4.1", + "qs": "^6.14.0", "raw-body": "^3.0.0", - "type-is": "~1.6.18" + "type-is": "^2.0.0" }, "engines": { "node": ">=18" } }, - "node_modules/body-parser/node_modules/debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/iconv-lite": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", - "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, - "node_modules/body-parser/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/body-parser/node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -3685,9 +3694,9 @@ } }, "node_modules/call-bind-apply-helpers": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.1.tgz", - "integrity": "sha512-BhYE+WDaywFg2TBWYNXAE+8B1ATnThNBqXHP5nQu0jWJdVvY2hvkpyB3qOmtmDePiS5/BDQ8wASEWGMWRG148g==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -3698,13 +3707,13 @@ } }, "node_modules/call-bound": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz", - "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "get-intrinsic": "^1.2.6" + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" }, "engines": { "node": ">= 0.4" @@ -3732,9 +3741,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001696", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001696.tgz", - "integrity": "sha512-pDCPkvzfa39ehJtJ+OwGT/2yvT2SbjfHhiIW2LWOAcMQ7BzwxT/XuyUp4OTOd0XFWA6BKw0JalnBHgSi5DGJBQ==", + "version": "1.0.30001713", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001713.tgz", + "integrity": "sha512-wCIWIg+A4Xr7NfhTuHdX+/FKh3+Op3LBbSp2N5Pfx6T/LhdQy3GTyoTg48BReaW/MyMNZAkTadsBtai3ldWK0Q==", "funding": [ { "type": "opencollective", @@ -3825,9 +3834,9 @@ } }, "node_modules/cjs-module-lexer": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.1.tgz", - "integrity": "sha512-cuSVIHi9/9E/+821Qjdvngor+xpnlwnuwIyZOaLmHBVdXL+gP+I6QQB9VkO7RI77YIcTV+S1W9AreJ5eN63JBA==", + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz", + "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==", "license": "MIT" }, "node_modules/clean-webpack-plugin": { @@ -4091,9 +4100,9 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "dev": true, "license": "MIT", "engines": { @@ -4111,13 +4120,13 @@ } }, "node_modules/core-js-compat": { - "version": "3.40.0", - "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.40.0.tgz", - "integrity": "sha512-0XEDpr5y5mijvw8Lbc6E5AkjrHfp7eEoPlu36SWeAbcL8fn1G1ANe8DBlo2XoNN89oVpxWwOjYIPVzR4ZvsKCQ==", + "version": "3.41.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", + "integrity": "sha512-RFsU9LySVue9RTwdDVX/T0e2Y6jRYWXERKElIjpuEOEnxaXffI0X7RUwVzfYLfzuLXSNJDYoRYUAmRUcyln20A==", "dev": true, "license": "MIT", "dependencies": { - "browserslist": "^4.24.3" + "browserslist": "^4.24.4" }, "funding": { "type": "opencollective", @@ -4177,13 +4186,13 @@ } }, "node_modules/cssstyle": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.2.1.tgz", - "integrity": "sha512-9+vem03dMXG7gDmZ62uqmRiMRNtinIZ9ZyuF6BdxzfOD+FdN5hretzynkn0ReS2DO2GSw76RWHs0UmJPI2zUjw==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.3.0.tgz", + "integrity": "sha512-6r0NiY0xizYqfBvWp1G7WXJ06/bZyrk7Dc6PHql82C/pKGUTKu4yAX4Y8JPamb1ob9nBKuxWzCGTRuGwU3yxJQ==", "dev": true, "license": "MIT", "dependencies": { - "@asamuzakjp/css-color": "^2.8.2", + "@asamuzakjp/css-color": "^3.1.1", "rrweb-cssom": "^0.8.0" }, "engines": { @@ -4204,43 +4213,6 @@ "node": ">=18" } }, - "node_modules/data-urls/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/data-urls/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/data-urls/node_modules/whatwg-url": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", - "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/data-view-buffer": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.2.tgz", @@ -4473,17 +4445,6 @@ "node": ">=6" } }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -4514,42 +4475,102 @@ "node": ">= 10.14.2" } }, - "node_modules/dotenv": { - "version": "16.4.7", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz", - "integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://dotenvx.com" - } - }, - "node_modules/dotignore": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", - "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", + "node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", "dev": true, "license": "MIT", "dependencies": { - "minimatch": "^3.0.4" - }, - "bin": { - "ignored": "bin/ignored" + "domelementtype": "^2.0.1", + "entities": "^2.0.0" } }, - "node_modules/dunder-proto": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", - "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "license": "MIT", - "dependencies": { - "call-bind-apply-helpers": "^1.0.1", - "es-errors": "^1.3.0", - "gopd": "^1.2.0" - }, + "node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", + "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/domutils": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", + "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/dotenv": { + "version": "16.5.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", + "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, + "node_modules/dotignore": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/dotignore/-/dotignore-0.1.2.tgz", + "integrity": "sha512-UGGGWfSauusaVJC+8fgV+NVvBXkCTmVv7sk6nojDZZvuOUNGUy0Zk4UpHQD6EDjS0jpBwcACvH4eofvyzBcRDw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimatch": "^3.0.4" + }, + "bin": { + "ignored": "bin/ignored" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, "engines": { "node": ">= 0.4" } @@ -4595,9 +4616,9 @@ } }, "node_modules/electron-to-chromium": { - "version": "1.5.90", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.90.tgz", - "integrity": "sha512-C3PN4aydfW91Natdyd449Kw+BzhLmof6tzy5W1pFC5SpQxVXT+oyiyOG9AgYYSN9OdA/ik3YkCrpwqI8ug5Tug==", + "version": "1.5.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.137.tgz", + "integrity": "sha512-/QSJaU2JyIuTbbABAo/crOs+SuAZLS+fVVS10PVrIT9hrRkmZl8Hb0xPSkKRUUWHQtYzXHpQUW3Dy5hwMzGZkA==", "license": "ISC" }, "node_modules/emittery": { @@ -4639,9 +4660,9 @@ } }, "node_modules/enhanced-resolve": { - "version": "5.18.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.0.tgz", - "integrity": "sha512-0/r0MySGYG8YqlayBZ6MuCfECmHFdJ5qyPh8s8wa5Hnm6SaFLSK1VYCbj+NKp090Nm1caZhD+QTnmxO7esYGyQ==", + "version": "5.18.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.1.tgz", + "integrity": "sha512-ZSW3ma5GkcQBIpwZTSRAI8N71Uuwgs93IezB7mf7R60tC8ZbJideoDNKjHn2O9KIlx6rkGTTEk1xUCK2E1Y2Yg==", "dev": true, "license": "MIT", "dependencies": { @@ -4653,17 +4674,11 @@ } }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } + "license": "BSD-like" }, "node_modules/envinfo": { "version": "7.14.0", @@ -5065,88 +5080,46 @@ } }, "node_modules/express": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", - "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", + "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", "dev": true, "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.0.1", + "body-parser": "^2.2.0", "content-disposition": "^1.0.0", - "content-type": "~1.0.4", - "cookie": "0.7.1", + "content-type": "^1.0.5", + "cookie": "^0.7.1", "cookie-signature": "^1.2.1", - "debug": "4.3.6", - "depd": "2.0.0", - "encodeurl": "~2.0.0", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "^2.0.0", - "fresh": "2.0.0", - "http-errors": "2.0.0", + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", "merge-descriptors": "^2.0.0", - "methods": "~1.1.2", "mime-types": "^3.0.0", - "on-finished": "2.4.1", - "once": "1.4.0", - "parseurl": "~1.3.3", - "proxy-addr": "~2.0.7", - "qs": "6.13.0", - "range-parser": "~1.2.1", - "router": "^2.0.0", - "safe-buffer": "5.2.1", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", "send": "^1.1.0", - "serve-static": "^2.1.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "^2.0.0", - "utils-merge": "1.0.1", - "vary": "~1.1.2" + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { "node": ">= 18" - } - }, - "node_modules/express/node_modules/debug": { - "version": "4.3.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", - "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true, - "license": "MIT" - }, - "node_modules/express/node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" }, "funding": { - "url": "https://github.com/sponsors/ljharb" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/fast-deep-equal": { @@ -5199,15 +5172,14 @@ } }, "node_modules/fetch-mock": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-12.3.0.tgz", - "integrity": "sha512-+ZHzLuzrKpP3u5PZo8ghFP1Kr3UJUTZ5PT/uQZtLv7UagDCVRt1bSzVg6MoTFdjQ0GXsx/crq2t0tGabkbH2yA==", + "version": "12.5.2", + "resolved": "https://registry.npmjs.org/fetch-mock/-/fetch-mock-12.5.2.tgz", + "integrity": "sha512-b5KGDFmdmado2MPQjZl6ix3dAG3iwCitb0XQwN72y2s9VnWZ3ObaGNy+bkpm1390foiLDybdJ7yjRGKD36kATw==", "license": "MIT", "dependencies": { "@types/glob-to-regexp": "^0.4.4", "dequal": "^2.0.3", "glob-to-regexp": "^0.4.1", - "is-subset-of": "^3.1.10", "regexparam": "^3.0.0" }, "engines": { @@ -5260,51 +5232,23 @@ } }, "node_modules/finalhandler": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.0.0.tgz", - "integrity": "sha512-MX6Zo2adDViYh+GcxxB1dpO43eypOGUOL12rLCOTMQv/DfIbpSJUy4oQIIZhVZkH9e+bZWKMon0XHFEju16tkQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", + "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", "dev": true, "license": "MIT", "dependencies": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { "node": ">= 0.8" } }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/find-cache-dir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", @@ -5367,9 +5311,9 @@ } }, "node_modules/for-each": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.4.tgz", - "integrity": "sha512-kKaIINnFpzW6ffJNDjjyjrk21BkDx38c0xa/klsT8VzLCaMEefv4ZTacrcVR4DmgTeBra++jMDAfS/tS799YDw==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.5.tgz", + "integrity": "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==", "dev": true, "license": "MIT", "dependencies": { @@ -5383,14 +5327,15 @@ } }, "node_modules/form-data": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.1.tgz", - "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" }, "engines": { @@ -5461,6 +5406,20 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -5520,17 +5479,17 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", - "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.1", + "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", + "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", - "get-proto": "^1.0.0", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", @@ -5820,6 +5779,20 @@ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", "license": "MIT" }, + "node_modules/htmlparser2": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "1", + "domhandler": "2.3", + "domutils": "1.5", + "entities": "1.0", + "readable-stream": "1.1" + } + }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", @@ -6057,13 +6030,13 @@ } }, "node_modules/is-boolean-object": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.1.tgz", - "integrity": "sha512-l9qO6eFlUETHtuihLcYOaLKByJ1f+N4kthcU9YjHy3N+B3hWv0y/2Nd0mu/7lTFnRQHTrSdXF50HQ3bl5fEnng==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.2.2.tgz", + "integrity": "sha512-wa56o2/ElJMYqjCjGkXri7it5FbebW5usLw/nPmCMs5DeZ7eziSYZhSmPRn0txqeW4LnAmQQU7FgqLpsEFKM4A==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2", + "call-bound": "^1.0.3", "has-tostringtag": "^1.0.2" }, "engines": { @@ -6396,16 +6369,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-subset-of": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/is-subset-of/-/is-subset-of-3.1.10.tgz", - "integrity": "sha512-avvaYgVmYWyaZ1NDFiv4y9JGkrE2je3op1Po4VYKKJKR8H2qVPsg1GZuuXl5elCTxTlwAIsrAjWAs4BVrISFRw==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT", - "dependencies": { - "typedescriptor": "3.0.2" - } - }, "node_modules/is-symbol": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.1.1.tgz", @@ -6454,13 +6417,13 @@ } }, "node_modules/is-weakref": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.0.tgz", - "integrity": "sha512-SXM8Nwyys6nT5WP6pltOwKytLV7FqQ4UiibxVmW+EIosHcmCqkkjViTb5SNssDlkCiEYRP1/pdWUKVvZBmsR2Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.1.1.tgz", + "integrity": "sha512-6i9mGWSlqzNMEqpCp93KwRS1uUOodk2OJ6b+sq7ZPDSy2WuI5NFIxp/254TytR8ftefexkWn5xNiHUNpPOfSew==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.2" + "call-bound": "^1.0.3" }, "engines": { "node": ">= 0.4" @@ -6500,9 +6463,9 @@ } }, "node_modules/isarray": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", - "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true, "license": "MIT" }, @@ -6548,9 +6511,9 @@ } }, "node_modules/istanbul-lib-instrument/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7374,9 +7337,9 @@ "license": "MIT" }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -7592,16 +7555,15 @@ } }, "node_modules/jsdom": { - "version": "26.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.0.0.tgz", - "integrity": "sha512-BZYDGVAIriBWTpIxYzrXjv3E/4u8+/pSG5bQdIYCbNCGOvsPkDQfTVLAIXAf9ETdCpduCVTkDe2NNZ8NIwUVzw==", + "version": "26.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-26.1.0.tgz", + "integrity": "sha512-Cvc9WUhxSMEo4McES3P7oK3QaXldCfNWp7pl2NNeiIFlCoLr3kfq9kb1fxftiwk1FLV7CvpvDfonxtzUDeSOPg==", "dev": true, "license": "MIT", "dependencies": { "cssstyle": "^4.2.1", "data-urls": "^5.0.0", - "decimal.js": "^10.4.3", - "form-data": "^4.0.1", + "decimal.js": "^10.5.0", "html-encoding-sniffer": "^4.0.0", "http-proxy-agent": "^7.0.2", "https-proxy-agent": "^7.0.6", @@ -7611,12 +7573,12 @@ "rrweb-cssom": "^0.8.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^5.0.0", + "tough-cookie": "^5.1.1", "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^3.1.1", "whatwg-mimetype": "^4.0.0", - "whatwg-url": "^14.1.0", + "whatwg-url": "^14.1.1", "ws": "^8.18.0", "xml-name-validator": "^5.0.0" }, @@ -7632,43 +7594,6 @@ } } }, - "node_modules/jsdom/node_modules/tr46": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", - "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", - "dev": true, - "license": "MIT", - "dependencies": { - "punycode": "^2.3.1" - }, - "engines": { - "node": ">=18" - } - }, - "node_modules/jsdom/node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/jsdom/node_modules/whatwg-url": { - "version": "14.1.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.1.0.tgz", - "integrity": "sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==", - "dev": true, - "license": "MIT", - "dependencies": { - "tr46": "^5.0.0", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -7700,94 +7625,6 @@ "jshint": "bin/jshint" } }, - "node_modules/jshint/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/jshint/node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "license": "BSD-2-Clause" - }, - "node_modules/jshint/node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "license": "BSD-2-Clause", - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/jshint/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true, - "license": "BSD-2-Clause" - }, - "node_modules/jshint/node_modules/domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha512-q9bUwjfp7Eif8jWxxxPSykdRZAb6GkguBGSgvvCrhI9wB71W2K/Kvv4E61CF/mcCfnVJDeDWx/Vb/uAqbDj6UQ==", - "dev": true, - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/jshint/node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/jshint/node_modules/entities": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", - "integrity": "sha512-LbLqfXgJMmy81t+7c14mnulFHJ170cM6E+0vMXR9k/ZiZwgX8i5pNgjTCX3SO4VeUsFLV+8InixoretwU+MjBQ==", - "dev": true, - "license": "BSD-like" - }, - "node_modules/jshint/node_modules/htmlparser2": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", - "integrity": "sha512-hBxEg3CYXe+rPIua8ETe7tmG3XDn9B0edOE/e9wH2nLczxzgdu0m0aNHY+5wFZiviLWLdANPJTssa92dMcXQ5Q==", - "dev": true, - "license": "MIT", - "dependencies": { - "domelementtype": "1", - "domhandler": "2.3", - "domutils": "1.5", - "entities": "1.0", - "readable-stream": "1.1" - } - }, - "node_modules/jshint/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true, - "license": "MIT" - }, "node_modules/jshint/node_modules/minimatch": { "version": "3.0.8", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", @@ -7801,26 +7638,6 @@ "node": "*" } }, - "node_modules/jshint/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/jshint/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true, - "license": "MIT" - }, "node_modules/jshint/node_modules/strip-json-comments": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz", @@ -7903,9 +7720,9 @@ } }, "node_modules/jsonwebtoken/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -8176,9 +7993,9 @@ } }, "node_modules/make-dir/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8239,6 +8056,19 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/markdown-it/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -8309,16 +8139,6 @@ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", "license": "MIT" }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", @@ -8333,9 +8153,9 @@ } }, "node_modules/mime-db": { - "version": "1.53.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", - "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", + "version": "1.54.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", + "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", "dev": true, "license": "MIT", "engines": { @@ -8343,13 +8163,13 @@ } }, "node_modules/mime-types": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", - "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", + "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", "dev": true, "license": "MIT", "dependencies": { - "mime-db": "^1.53.0" + "mime-db": "^1.54.0" }, "engines": { "node": ">= 0.6" @@ -8426,6 +8246,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/mock-property/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -8548,9 +8375,9 @@ } }, "node_modules/nodemailer": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.0.tgz", - "integrity": "sha512-SQ3wZCExjeSatLE/HBaXS5vqUOQk6GtBdIIKxiFdmm01mOQZX/POJkO3SUX1wDiYcwUOJwT23scFSC9fY2H8IA==", + "version": "6.10.1", + "resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-6.10.1.tgz", + "integrity": "sha512-Z+iLaBGVaSjbIzQ4pX6XV41HrooLsQ10ZWPUehGmuantvzWoDVBnmsdUcOIDM1t+yPor5pDhVlDESgOMEGxhHA==", "dev": true, "license": "MIT-0", "engines": { @@ -8579,9 +8406,9 @@ } }, "node_modules/nwsapi": { - "version": "2.2.16", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.16.tgz", - "integrity": "sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==", + "version": "2.2.20", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.20.tgz", + "integrity": "sha512-/ieB+mDe4MrrKMT8z+mQL8klXydZWGR5Dowt4RAGKbJ3kIGEx3X4ljUo+6V73IXtUPWgfOlU5B9MlGxFO5T+cA==", "dev": true, "license": "MIT" }, @@ -8596,9 +8423,9 @@ } }, "node_modules/object-inspect": { - "version": "1.13.3", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz", - "integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==", + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", "license": "MIT", "engines": { "node": ">= 0.4" @@ -8881,6 +8708,19 @@ "url": "https://github.com/inikulin/parse5?sponsor=1" } }, + "node_modules/parse5/node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -8993,9 +8833,9 @@ } }, "node_modules/pirates": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", - "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.7.tgz", + "integrity": "sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==", "license": "MIT", "engines": { "node": ">= 6" @@ -9093,9 +8933,9 @@ } }, "node_modules/pkg-dir/node_modules/yocto-queue": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.1.1.tgz", - "integrity": "sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", "dev": true, "license": "MIT", "engines": { @@ -9106,9 +8946,9 @@ } }, "node_modules/possible-typed-array-names": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", - "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.1.0.tgz", + "integrity": "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==", "dev": true, "license": "MIT", "engines": { @@ -9324,18 +9164,16 @@ "license": "MIT" }, "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "version": "1.1.14", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", "dev": true, "license": "MIT", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" } }, "node_modules/recast": { @@ -9636,22 +9474,20 @@ } }, "node_modules/router": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/router/-/router-2.0.0.tgz", - "integrity": "sha512-dIM5zVoG8xhC6rnSN8uoAgFARwTE7BQs8YwHEvK0VCmfxQXMaOuA1uiR1IPwsW7JyK5iTt7Od/TC9StasS2NPQ==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", "dev": true, "license": "MIT", "dependencies": { - "array-flatten": "3.0.0", - "is-promise": "4.0.0", - "methods": "~1.1.2", - "parseurl": "~1.3.3", - "path-to-regexp": "^8.0.0", - "setprototypeof": "1.2.0", - "utils-merge": "1.0.1" + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 18" } }, "node_modules/rrweb-cssom": { @@ -9681,6 +9517,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-array-concat/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-buffer": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", @@ -9719,6 +9562,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/safe-push-apply/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/safe-regex-test": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", @@ -9806,20 +9656,19 @@ } }, "node_modules/send": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", - "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", "dev": true, "license": "MIT", "dependencies": { "debug": "^4.3.5", - "destroy": "^1.2.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", - "fresh": "^0.5.2", + "fresh": "^2.0.0", "http-errors": "^2.0.0", - "mime-types": "^2.1.35", + "mime-types": "^3.0.1", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", @@ -9829,39 +9678,6 @@ "node": ">= 18" } }, - "node_modules/send/node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/send/node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/send/node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, - "license": "MIT", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, "node_modules/serialize-javascript": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", @@ -9873,16 +9689,16 @@ } }, "node_modules/serve-static": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", - "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", "dev": true, "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "parseurl": "^1.3.3", - "send": "^1.0.0" + "send": "^1.2.0" }, "engines": { "node": ">= 18" @@ -10187,14 +10003,11 @@ "license": "MIT" }, "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "version": "0.10.31", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } + "license": "MIT" }, "node_modules/string-length": { "version": "4.0.2", @@ -10454,13 +10267,6 @@ "tap-json": "bin/tap-json" } }, - "node_modules/tap-json/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true, - "license": "MIT" - }, "node_modules/tap-json/node_modules/object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", @@ -10468,26 +10274,6 @@ "dev": true, "license": "MIT" }, - "node_modules/tap-json/node_modules/readable-stream": { - "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "node_modules/tap-json/node_modules/string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==", - "dev": true, - "license": "MIT" - }, "node_modules/tap-json/node_modules/tap-parser": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/tap-parser/-/tap-parser-0.4.3.tgz", @@ -10614,9 +10400,9 @@ } }, "node_modules/terser": { - "version": "5.37.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", - "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -10633,9 +10419,9 @@ } }, "node_modules/terser-webpack-plugin": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.11.tgz", - "integrity": "sha512-RVCsMfuD0+cTt3EwX8hSl2Ks56EbFHWmhluwcqoPKtBnfjiT6olaq7PRIRfhyU8nnC2MrnDrBLfrD/RGE+cVXQ==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", "dev": true, "license": "MIT", "dependencies": { @@ -10699,9 +10485,9 @@ } }, "node_modules/terser/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", "bin": { @@ -10753,23 +10539,48 @@ "readable-stream": "3" } }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/through2/node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, "node_modules/tldts": { - "version": "6.1.75", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.75.tgz", - "integrity": "sha512-+lFzEXhpl7JXgWYaXcB6DqTYXbUArvrWAE/5ioq/X3CdWLbDjpPP4XTrQBmEJ91y3xbe4Fkw7Lxv4P3GWeJaNg==", + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz", + "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==", "dev": true, "license": "MIT", "dependencies": { - "tldts-core": "^6.1.75" + "tldts-core": "^6.1.86" }, "bin": { "tldts": "bin/cli.js" } }, "node_modules/tldts-core": { - "version": "6.1.75", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.75.tgz", - "integrity": "sha512-AOvV5YYIAFFBfransBzSTyztkc3IMfz5Eq3YluaRiEu55nn43Fzaufx70UqEKYr8BoLCach4q8g/bg6e5+/aFw==", + "version": "6.1.86", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz", + "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==", "dev": true, "license": "MIT" }, @@ -10802,9 +10613,9 @@ } }, "node_modules/tough-cookie": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.0.tgz", - "integrity": "sha512-rvZUv+7MoBYTiDmFPBrhL7Ujx9Sk+q9wwm22x8c8T5IJaR+Wsyc7TNxbVxo84kZoRJZZMazowFLqpankBEQrGg==", + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz", + "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -10814,10 +10625,23 @@ "node": ">=16" } }, + "node_modules/tr46": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.1.0.tgz", + "integrity": "sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/ts-jest": { - "version": "29.2.5", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.2.5.tgz", - "integrity": "sha512-KD8zB2aAZrcKIdGk4OwpJggeLcH1FgrICqDSROWqlnJXGCXK4Mn6FcdK2B6670Xr73lHMG1kHw8R87A0ecZ+vA==", + "version": "29.3.2", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.3.2.tgz", + "integrity": "sha512-bJJkrWc6PjFVz5g2DGCNUo8z7oFEYaz1xP1NpeDU7KNLMWPpEyV8Chbpkn8xjzgRDpQhnGMyvyldoL7h8JXyug==", "dev": true, "license": "MIT", "dependencies": { @@ -10828,7 +10652,8 @@ "json5": "^2.2.3", "lodash.memoize": "^4.1.2", "make-error": "^1.3.6", - "semver": "^7.6.3", + "semver": "^7.7.1", + "type-fest": "^4.39.1", "yargs-parser": "^21.1.1" }, "bin": { @@ -10864,9 +10689,9 @@ } }, "node_modules/ts-jest/node_modules/semver": { - "version": "7.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.0.tgz", - "integrity": "sha512-DrfFnPzblFmNrIZzg5RzHegbiRWg7KMR7btwi2yjHwx06zsUbO5g613sVwEV7FTwmzJu+Io0lJe2GJ3LxqpvBQ==", + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", "dev": true, "license": "ISC", "bin": { @@ -10876,6 +10701,19 @@ "node": ">=10" } }, + "node_modules/ts-jest/node_modules/type-fest": { + "version": "4.40.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-4.40.0.tgz", + "integrity": "sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/tsscmp": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", @@ -10908,9 +10746,9 @@ } }, "node_modules/type-is": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", - "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", "dev": true, "license": "MIT", "dependencies": { @@ -11000,13 +10838,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/typedescriptor": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/typedescriptor/-/typedescriptor-3.0.2.tgz", - "integrity": "sha512-hyVbaCUd18UiXk656g/imaBLMogpdijIEpnhWYrSda9rhvO4gOU16n2nh7xG5lv/rjumnZzGOdz0CEGTmFe0fQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "license": "MIT" - }, "node_modules/typescript": { "version": "4.9.5", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", @@ -11068,9 +10899,9 @@ "license": "MIT" }, "node_modules/undici-types": { - "version": "6.20.0", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz", - "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==", + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", + "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { @@ -11138,9 +10969,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.2.tgz", - "integrity": "sha512-PPypAm5qvlD7XMZC3BujecnaOxwhrtoFR+Dqkk5Aa/6DssiH0ibKoketaj9w8LP7Bont1rYeoV5plxD7RTEPRg==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", "funding": [ { "type": "opencollective", @@ -11184,16 +11015,6 @@ "dev": true, "license": "MIT" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, "node_modules/v8-to-istanbul": { "version": "9.3.0", "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", @@ -11254,10 +11075,20 @@ "node": ">=10.13.0" } }, + "node_modules/webidl-conversions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", + "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } + }, "node_modules/webpack": { - "version": "5.97.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.97.1.tgz", - "integrity": "sha512-EksG6gFY3L1eFMROS/7Wzgrii5mBAFe4rIr3r2BTfo7bcc+DWwFZ4OJ/miOuHJO/A85HwyI4eQ0F6IKXesO7Fg==", + "version": "5.99.5", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.99.5.tgz", + "integrity": "sha512-q+vHBa6H9qwBLUlHL4Y7L0L1/LlyBKZtS9FHNCQmtayxjI5RKC9yD8gpvLeqGv5lCQp1Re04yi0MF40pf30Pvg==", "dev": true, "license": "MIT", "dependencies": { @@ -11279,9 +11110,9 @@ "loader-runner": "^4.2.0", "mime-types": "^2.1.27", "neo-async": "^2.6.2", - "schema-utils": "^3.2.0", + "schema-utils": "^4.3.0", "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.10", + "terser-webpack-plugin": "^5.3.11", "watchpack": "^2.4.1", "webpack-sources": "^3.2.3" }, @@ -11400,9 +11231,9 @@ } }, "node_modules/webpack/node_modules/acorn": { - "version": "8.14.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz", - "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==", + "version": "8.14.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.1.tgz", + "integrity": "sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg==", "dev": true, "license": "MIT", "bin": { @@ -11412,40 +11243,6 @@ "node": ">=0.4.0" } }, - "node_modules/webpack/node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack/node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "node_modules/webpack/node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true, - "license": "MIT" - }, "node_modules/webpack/node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -11469,25 +11266,6 @@ "node": ">= 0.6" } }, - "node_modules/webpack/node_modules/schema-utils": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", - "integrity": "sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", @@ -11511,6 +11289,20 @@ "node": ">=18" } }, + "node_modules/whatwg-url": { + "version": "14.2.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.2.0.tgz", + "integrity": "sha512-De72GdQZzNTUBBChsXueQUnPKDkg/5A5zp7pFDuQAj5UFoENpiACU0wlCvzpAGnTkj++ihpKwKyYewn/XNUbKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tr46": "^5.1.0", + "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", @@ -11593,6 +11385,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/which-builtin-type/node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true, + "license": "MIT" + }, "node_modules/which-collection": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/which-collection/-/which-collection-1.0.2.tgz", @@ -11613,16 +11412,17 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.18", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.18.tgz", - "integrity": "sha512-qEcY+KJYlWyLH9vNbsr6/5j59AXk5ni5aakf8ldzBvGde6Iz4sxZGkJyWSAueTG7QhOvNRYb1lDdFmL5Td0QKA==", + "version": "1.1.19", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", + "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "for-each": "^0.3.3", + "call-bound": "^1.0.4", + "for-each": "^0.3.5", + "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" }, @@ -11677,9 +11477,9 @@ } }, "node_modules/ws": { - "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", - "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-RKW2aJZMXeMxVpnZ6bck+RswznaxmzdULiBr6KY7XkTnW8uvt0iT9H5DkHUChXrc+uurzwa0rVI16n/Xzjdz1w==", "dev": true, "license": "MIT", "engines": { diff --git a/package.json b/package.json index cecc8176..e6437a8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "contentstack", - "version": "3.24.3", + "version": "3.25.3", "description": "Contentstack Javascript SDK", "homepage": "https://www.contentstack.com/", "author": { @@ -14,7 +14,7 @@ "_id": "contentstack@3.19.3", "scripts": { "test": "npm run test:e2e && npm run test:typescript", - "test:e2e": "tape test/index.js | tap-html --out ./tap-html.html", + "test:e2e": "jest --config jest.js.config.js", "test:typescript": "jest --config jest.config.js --testPathPattern=test/typescript", "automate": "node test.js", "build:node": "webpack --config webpack/webpack.node.js", @@ -100,10 +100,10 @@ "webpack-node-externals": "^3.0.0" }, "dependencies": { - "@contentstack/utils": "^1.3.15", - "@fetch-mock/jest": "^0.2.10", + "@contentstack/utils": "^1.3.20", + "@fetch-mock/jest": "^0.2.15", "es6-promise": "^4.2.8", - "fetch-mock": "^12.2.0", + "fetch-mock": "^12.5.2", "localStorage": "1.0.4", "qs": "^6.14.0" } diff --git a/sanity-report-dev11.js b/sanity-report-dev11.js index eea37a6d..6c4ba11e 100644 --- a/sanity-report-dev11.js +++ b/sanity-report-dev11.js @@ -1,6 +1,8 @@ const fs = require("fs"); +const { App } = require("@slack/bolt"); const { JSDOM } = require("jsdom"); const dotenv = require("dotenv"); +const path = require("path"); dotenv.config(); @@ -9,40 +11,38 @@ const user2 = process.env.USER2; const user3 = process.env.USER3; const user4 = process.env.USER4; -const tapHtmlContent = fs.readFileSync("./tap-html.html", "utf8"); -const dom = new JSDOM(tapHtmlContent); -const $ = require("jquery")(dom.window); - -const totalCount = $(".nav a:nth-child(2)") - .text() - .trim() - .replace("Total Count", ""); -const totalPass = $(".nav a:nth-child(3)") - .text() - .trim() - .replace("Total Pass", ""); -const totalFail = $(".nav a:nth-child(4)") - .text() - .trim() - .replace("Total Fail", ""); - -const totalTime = $(".nav a:nth-child(1)") - .text() - .trim() - .replace("Total Time", ""); - -const milliseconds = parseInt(totalTime.replace(/\D/g, ''), 10); -const totalSeconds = Math.floor(milliseconds / 1000); -const durationInMinutes = Math.floor(totalSeconds / 60); -const durationInSeconds = totalSeconds % 60; - -const passedTests = parseInt(totalPass, 10); -const totalTests = parseInt(totalCount, 10); +const data = fs.readFileSync(path.join(__dirname, "tap-html.html"), "utf8"); +const dom = new JSDOM(data); +const textarea = dom.window.document.querySelector( + "#jest-html-reports-result-data" +); +const testResults = JSON.parse(textarea.textContent.trim()); + +const startTime = testResults.startTime; +const endTime = Math.max( + ...testResults.testResults.map((t) => t.perfStats.end) +); +const totalSeconds = (endTime - startTime) / 1000; +const minutes = Math.floor(totalSeconds / 60); +const seconds = (totalSeconds % 60).toFixed(2); +const duration = `${minutes}m ${seconds}s`; + +const summary = { + totalSuites: testResults.numTotalTestSuites, + passedSuites: testResults.numPassedTestSuites, + failedSuites: testResults.numFailedTestSuites, + totalTests: testResults.numTotalTests, + passedTests: testResults.numPassedTests, + failedTests: testResults.numFailedTests, + skippedTests: testResults.numPendingTests + testResults.numTodoTests, + pendingTests: testResults.numPendingTests, + duration: duration, +}; const resultMessage = - passedTests === totalTests - ? `:white_check_mark: Success (${passedTests} / ${totalTests} Passed)` - : `:x: Failure (${passedTests} / ${totalTests} Passed)`; + summary.passedTests === summary.totalTests + ? `:white_check_mark: Success (${summary.passedTests} / ${summary.totalTests} Passed)` + : `:x: Failure (${summary.passedTests} / ${summary.totalTests} Passed)`; const pipelineName = process.env.GO_PIPELINE_NAME; const pipelineCounter = process.env.GO_PIPELINE_COUNTER; @@ -51,42 +51,65 @@ const goCdServer = process.env.GOCD_SERVER; const reportUrl = `http://${goCdServer}/go/files/${pipelineName}/${pipelineCounter}/sanity/1/sanity/test-results/tap-html.html`; let tagUsers = ``; -if (totalFail > 0) { +if (summary.failedTests > 0) { tagUsers = `<@${user1}> <@${user2}> <@${user3}> <@${user4}>`; } const slackMessage = { text: `Dev11, SDK-CDA Sanity -*Result:* ${resultMessage}. ${durationInMinutes}m ${durationInSeconds}s -*Failed Tests:* ${totalFail} +*Result:* ${resultMessage}. ${summary.duration}s +*Failed Tests:* ${summary.failedTests + summary.skippedTests} <${reportUrl}|View Report> ${tagUsers}`, }; -const slackWebhookUrl = process.env.SLACK_WEBHOOK_URL; - -const sendSlackMessage = async (message) => { - const payload = { - text: message, - }; +const app = new App({ + token: process.env.SLACK_BOT_TOKEN, + signingSecret: process.env.SLACK_SIGNING_SECRET, +}); +const sendSlackMessage = async () => { try { - const response = await fetch(slackWebhookUrl, { - method: "POST", - headers: { - "Content-Type": "application/json", - }, - body: JSON.stringify(payload), + const result = await app.client.chat.postMessage({ + token: process.env.SLACK_BOT_TOKEN, + channel: process.env.SLACK_CHANNEL2, + text: slackMessage.text, // Ensure this is the full object }); - if (!response.ok) { - throw new Error(`Error sending message to Slack: ${response.statusText}`); + if (summary.failedTests > 0) { + await sendFailureDetails(result.ts); // Pass the correct thread timestamp } - - console.log("Message sent to Slack successfully"); } catch (error) { - console.error("Error:", error); + console.error("Error sending Slack message:", error); + } +}; + +const sendFailureDetails = async (threadTs) => { + const failedTestSuites = testResults.testResults.filter( + (suite) => suite.numFailingTests > 0 + ); + if (failedTestSuites.length > 0) { + let failureDetails = "*Failed Test Modules:*\n"; + for (const suite of failedTestSuites) { + let modulePath = suite.testFilePath; + let formattedModuleName = path + .relative(__dirname, modulePath) + .replace(/^test\//, "") + .replace(/\.js$/, "") + .replace(/\//g, " "); + failureDetails += ` - ${formattedModuleName}: ${suite.numFailingTests} failed\n`; + } + try { + await app.client.chat.postMessage({ + token: process.env.SLACK_BOT_TOKEN, + channel: process.env.SLACK_CHANNEL2, + text: failureDetails, + thread_ts: threadTs, + }); + } catch (error) { + console.error("Error sending failure details:", error); + } } }; -sendSlackMessage(slackMessage.text); \ No newline at end of file +sendSlackMessage(slackMessage.text); diff --git a/sanity-report.js b/sanity-report.js index 38810001..9a664f4d 100644 --- a/sanity-report.js +++ b/sanity-report.js @@ -2,42 +2,52 @@ const fs = require('fs'); const { App } = require('@slack/bolt'); const { JSDOM } = require("jsdom"); const dotenv = require('dotenv') +const path = require("path"); + dotenv.config() -const tapHtmlContent = fs.readFileSync('./tap-html.html', 'utf8'); -const report = `./tap-html.html` -const dom = new JSDOM(tapHtmlContent); -const $ = require("jquery")(dom.window); +const data = fs.readFileSync(path.join(__dirname, 'tap-html.html'), 'utf8'); +const dom = new JSDOM(data); +const report = './tap-html.html' +const textarea = dom.window.document.querySelector("#jest-html-reports-result-data"); +const testResults = JSON.parse(textarea.textContent.trim()); -const totalTime = $('.nav a:nth-child(1)').text().trim().replace('Total Time', ''); -const totalCount = $('.nav a:nth-child(2)').text().trim().replace('Total Count', ''); -const totalPass = $('.nav a:nth-child(3)').text().trim().replace('Total Pass', ''); -const totalFail = $('.nav a:nth-child(4)').text().trim().replace('Total Fail', ''); -const totalSkip = $('.nav a:nth-child(5)').text().trim().replace('Total Skip', ''); -const totalTodo = $('.nav a:nth-child(6)').text().trim().replace('Total Todo', ''); +const startTime = testResults.startTime; +const endTime = Math.max(...testResults.testResults.map(t => t.perfStats.end)); +const totalSeconds = (endTime - startTime) / 1000; +const minutes = Math.floor(totalSeconds / 60); +const seconds = (totalSeconds % 60).toFixed(2); +const duration = `${minutes}m ${seconds}s`; -const milliseconds = parseInt(totalTime.replace(/\D/g, ''), 10); -const totalSeconds = Math.floor(milliseconds / 1000); -const durationInMinutes = Math.floor(totalSeconds / 60); -const durationInSeconds = totalSeconds % 60; +const summary = { + totalSuites: testResults.numTotalTestSuites, + passedSuites: testResults.numPassedTestSuites, + failedSuites: testResults.numFailedTestSuites, + totalTests: testResults.numTotalTests, + passedTests: testResults.numPassedTests, + failedTests: testResults.numFailedTests, + skippedTests: testResults.numPendingTests + testResults.numTodoTests, + pendingTests: testResults.numPendingTests, + duration: duration, +}; -console.log('Total Test Suits:', '9') -console.log('Total Tests:', totalCount); -console.log('Total Pass:', totalPass); -console.log('Total Fail:', totalFail); -console.log('Total Skip:', totalSkip); -console.log('Total Pending:', totalTodo); -console.log('Total Duration:', `${durationInMinutes}m`,`${durationInSeconds.toFixed(2)}s`); +console.log('Total Test Suits:', summary.totalSuites) +console.log('Total Tests:', summary.totalTests); +console.log('Total Pass:', summary.passedTests); +console.log('Total Fail:', summary.failedTests); +console.log('Total Skip:', summary.skippedTests); +console.log('Total Pending:', summary.pendingTests); +console.log('Total Duration:', summary.duration); const slackMessage = ` *Test Summary of JS Delivery SDK* -• Total Test Suits: *9* -• Total Tests: *${totalCount}* -• Total Pass:: *${totalPass}* -• Total Fail: *${totalFail}* -• Total Skip:: *${totalSkip}* -• Total Pending: *${totalTodo}* -• Total Duration: *${durationInMinutes}m ${durationInSeconds}s* +• Total Test Suits: *${summary.totalSuites}* +• Total Tests: *${summary.totalTests}* +• Total Pass:: *${summary.passedTests}* +• Total Fail: *${summary.failedTests}* +• Total Skip:: *${summary.skippedTests}* +• Total Pending: *${summary.pendingTests}* +• Total Duration: *${duration}* ` const app = new App({ diff --git a/src/core/contentstackregion.js b/src/core/contentstackregion.js index 785fbe40..715dae01 100644 --- a/src/core/contentstackregion.js +++ b/src/core/contentstackregion.js @@ -4,6 +4,7 @@ const ContentstackRegion = { AZURE_NA: "azure-na", AZURE_EU: "azure-eu", GCP_NA: "gcp-na", + GCP_EU: "gcp-eu" }; export default ContentstackRegion; \ No newline at end of file diff --git a/src/core/stack.js b/src/core/stack.js index 599e1ff3..b9206fd3 100755 --- a/src/core/stack.js +++ b/src/core/stack.js @@ -596,8 +596,28 @@ export default class Stack { */ sync(params, fetchOptions) { + if (params && typeof params !== "object") { + throw new Error("Invalid parameters: params must be an object."); + } this._query = {}; - this._query = Utils.mergeDeep(this._query, params); + + if (params) { + for (const key in params) { + const value = params[key]; + if (params.hasOwnProperty(key)) { + if ( + typeof value !== "string" && + typeof value !== "number" && + typeof value !== "boolean" && + !(value instanceof RegExp) && + (typeof value !== "object" || value === null) + ) { + throw new Error(`Invalid parameter value for key "${key}": must be a string, number, object, boolean, or RegExp.`); + } + this._query[key] = params[key]; + } + } + } this.requestParams = { method: 'POST', headers: Utils.mergeDeep({}, this.headers), @@ -630,7 +650,9 @@ export default class Stack { if (url && typeof url === "string" && typeof params === "object" && params.length === undefined) { let queryParams = []; for (const operation in params) { - queryParams.push(operation + '=' + params[operation]); + const encodedKey = encodeURIComponent(operation); + const encodedValue = encodeURIComponent(params[operation]); + queryParams.push(encodedKey + '=' + encodedValue); } url += (url.indexOf("?") <= -1) ? "?" + queryParams.join('&') : "&" + queryParams.join('&'); } diff --git a/test/asset/find-result-wrapper.js b/test/asset/find-result-wrapper.js index bfcf8ad1..5c03e016 100755 --- a/test/asset/find-result-wrapper.js +++ b/test/asset/find-result-wrapper.js @@ -1,787 +1,1114 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -var test = require('tape'); -var Contentstack = require('../../dist/node/contentstack.js'); -var init = require('../config.js'); -var Utils = require('../entry/utils.js'); - -var Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - - -test('default .find() no fallback', function(assert) { - var _in = ['ja-jp'] - Stack.Assets().Query().language('ja-jp').toJSON().find() - .then((assets) => { - assert.ok(assets[0].length, 'Assets present in the resultset'); - assert.notok(assets[1], 'Count should not be present'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['publish_details']['locale']) != -1); - }); - assert.equal(_assets, true, "Publish content fallback"); - } - assert.end(); - }).catch((error) => { - assert.fail("asset default .find() fallback catch", error.toString()); - assert.end(); - }) -}) -test('default .find() fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.Assets().Query().language('ja-jp').includeFallback().toJSON().find() - .then((assets) => { - assert.ok(assets[0].length, 'Assets present in the resultset'); - assert.notok(assets[1], 'Count should not be present'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['publish_details']['locale']) != -1); - }); - assert.equal(_assets, true, "Publish content fallback"); - } - assert.end(); - }).catch((error) => { - assert.fail("asset default .find() fallback catch", error.toString()); - assert.end(); - }) -}) -test('default .find()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - Query - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(!assets[1], 'Count should not present in the result'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - prev = asset[field]; - return (asset.updated_at <= prev); - }); - assert.equal(_assets, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("default .find()"); - assert.end(); - }); -}); - -/*! - * SORTING - * !*/ -test('.ascending()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - - Query - .ascending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - prev = asset[field]; - return (asset[field] >= prev); - }); - assert.equal(_assets, true, "assets sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".ascending()"); - assert.end(); - }); -}); - -test('.descending()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'created_at'; - - Query - .descending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - prev = asset[field]; - return (asset[field] >= prev); - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".descending()"); - assert.end(); - }); -}); - - -/*! - * COMPARISION - * !*/ -test('.lessThan()', function(assert) { - var Query = Stack.Assets().Query(), - value = 5122, - field = 'updated_at'; - Query - .lessThan('file_size', value) - .language('en-us') - .toJSON() - .find() - .then(function success(assets) { - // assert.ok("assets" in result, 'assets key present in the resultset'); - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 1, 'one asset present in the resultset') - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = true; - _assets = assets[0].slice(1).every(function(asset) { - var flag = (asset[field] < value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThan()"); - assert.end(); - }); -}); - -test('.lessThanOrEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at', - value = 5122; - Query - .language('en-us') - .lessThanOrEqualTo('file_size', value) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 2, 'two assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThanOrEqualTo()"); - assert.end(); - }); -}); - -test('.greaterThan()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; - - Query - .greaterThan('file_size', value) - .ascending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 3, 'three assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].slice(1).every(function(asset) { - var flag = (asset[field] > value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThan()"); - assert.end(); - }); -}); - -test('.greaterThanOrEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; - - Query - .greaterThanOrEqualTo('file_size', value) - .descending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 4, 'four assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] >= value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThanOrEqualTo()"); - assert.end(); - }); -}); - -test('.notEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; - - Query - .language('en-us') - .notEqualTo('file_size', value) - .descending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 4, 'four assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] != value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notEqualTo()"); - assert.end(); - }); -}); - -/*! - * Array/Subset - * !*/ - -test('.containedIn()', function(assert) { - var Query = Stack.Assets().Query(), - _in = ["image1", "image2"], - field = 'updated_at'; - - Query - .containedIn('title', _in) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 2, 'two assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['title']) != -1); - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".containedIn()"); - assert.end(); - }); -}); - -test('.notContainedIn()', function(assert) { - var Query = Stack.Assets().Query(), - _in = ["sourceddd1", "sourceddddd2"]; - - Query - .notContainedIn('title', _in) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'No asset present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notContainedIn()"); - assert.end(); - }); -}); - - -/*! - *Element(exists) - * !*/ - -test('.exists()', function(assert) { - var Query = Stack.Assets().Query(), - queryField = "is_dir", - field = 'updated_at'; - - Query - .language('en-us') - .exists(queryField) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets should not be present in the resultset'); - assert.equal(assets[0].length, 5, 'five assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".exists()"); - assert.end(); - }); -}); - -test('.notExists()', function(assert) { - var Query = Stack.Assets().Query(), - queryField = "is_dir", - field = 'updated_at'; - - Query - .notExists(queryField) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, 'No asset present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notExists()"); - assert.end(); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); +const Utils = require("../entry/utils.js"); + +let Stack; + +describe("Contentstack Asset Tests", () => { + // Initialize the Contentstack Stack Instance + beforeAll(() => { + return new Promise((resolve) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(resolve, 1000); + }); + }); + + describe("default .find() No fallback", () => { + const _in = ["ja-jp"]; + let assets; + + // Setup - run the query once for all tests + beforeAll(async () => { + try { + assets = await Stack.Assets().Query().language("ja-jp").toJSON().find(); + } catch (error) { + console.error("Error in beforeAll:", error); + throw error; + } + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should not include count when not requested", async () => { + expect(assets[1]).toBeFalsy(); + }); + + test("should return assets only in the requested locale", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsInRequestedLocale = assets[0].every((asset) => { + return _in.indexOf(asset["publish_details"]["locale"]) !== -1; }); -}); - - -// Pagination -test('.skip()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - - Query - .toJSON() - .find() - .then(function success(allassets) { - // assert.ok("assets" in allassets, 'assets key present in the resultset'); - Stack - .Assets() - .Query() - .skip(1) - .toJSON() - .find() - .then(function success(assets) { - // assert.ok("assets" in result, 'assets key present in the resultset'); - assert.ok((assets[0].length >= 2), '2 or more assets present in the resultset'); - assert.deepEqual(allassets[0].slice(1), assets[0], 'All elements matched.'); - if (assets && assets.length && assets[0].length) { - allassets[0] = allassets[0].slice(1); - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(""); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail("skip()"); - assert.end(); + expect(allAssetsInRequestedLocale).toBe(true); + } else { + // Skip this test if no assets are returned + console.warn("No assets returned to verify locale"); + } + }); + + test("should have the correct structure for each asset", async () => { + if (assets && assets.length && assets[0].length) { + const firstAsset = assets[0][0]; + expect(firstAsset).toHaveProperty("uid"); + expect(firstAsset).toHaveProperty("title"); + expect(firstAsset).toHaveProperty("publish_details"); + expect(firstAsset.publish_details).toHaveProperty("locale"); + expect(firstAsset.publish_details.locale).toBe("ja-jp"); + } else { + // Skip this test if no assets are returned + console.warn("No assets returned to verify structure"); + } + }); + }); + + describe("default .find() with fallback", () => { + const _in = ["ja-jp", "en-us"]; + let assets; + + // Setup - run the query once for all tests + beforeAll(async () => { + try { + assets = await Stack.Assets() + .Query() + .language("ja-jp") + .includeFallback() + .toJSON() + .find(); + } catch (error) { + console.error("Error in beforeAll:", error); + throw error; + } + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should not include count when not requested", async () => { + expect(assets[1]).toBeFalsy(); + }); + + test("should return assets from both primary and fallback locales", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsInAllowedLocales = assets[0].every((asset) => { + return _in.indexOf(asset["publish_details"]["locale"]) !== -1; }); -}); - -test('.limit()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - - Query - .toJSON() - .find() - .then(function success(allassets) { - // assert.ok("assets" in allassets, 'assets key present in the resultset'); - Stack - .Assets() - .Query() - .limit(2) - .toJSON() - .find() - .then(function success(assets) { - // assert.ok("assets" in result, 'assets key present in the resultset'); - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.deepEqual(allassets[0].slice(0, 2), assets[0], 'All elements matched.'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); + expect(allAssetsInAllowedLocales).toBe(true); + } else { + // Skip this test if no assets are returned + console.warn("No assets returned to verify locales with fallback"); + } + }); + + test("should include some assets in primary locale", async () => { + if (assets && assets.length && assets[0].length) { + const anyAssetsInPrimaryLocale = assets[0].some((asset) => { + return asset["publish_details"]["locale"] === "ja-jp"; }); -}); - -test('.count()', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .count() - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0], 'assets count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".count()"); - assert.end(); + expect(anyAssetsInPrimaryLocale).toBe(true); + } else { + console.warn("No assets returned to verify primary locale presence"); + } + }); + + test("should have the correct structure for each asset", async () => { + if (assets && assets.length && assets[0].length) { + const firstAsset = assets[0][0]; + expect(firstAsset).toHaveProperty("uid"); + expect(firstAsset).toHaveProperty("title"); + expect(firstAsset).toHaveProperty("publish_details"); + expect(firstAsset.publish_details).toHaveProperty("locale"); + expect( + ["ja-jp", "en-us"].includes(firstAsset.publish_details.locale) + ).toBe(true); + } else { + console.warn("No assets returned to verify structure"); + } + }); + }); + + describe("default .find()", () => { + let assets; + const field = "updated_at"; + + // Setup - run the query once for all tests + beforeAll(async () => { + try { + const Query = Stack.Assets().Query(); + assets = await Query.toJSON().find(); + } catch (error) { + console.error("Error in beforeAll:", error); + throw error; + } + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should not include count when not requested", async () => { + expect(assets[1]).toBeFalsy(); + }); + + test("should return assets sorted by updated_at by default in descending order", async () => { + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const allAssetsSorted = assets[0].every((asset) => { + const isSorted = asset[field] <= prev; + prev = asset[field]; + return isSorted; }); -}); - - - -// Logical -test('.or() - Query Objects', function(assert) { - var Query1 = Stack.Assets().Query().containedIn('title', ['image1', 'image2']); - var Query2 = Stack.Assets().Query().where('is_dir', true); - var Query = Stack.Assets().Query(); - - Query - .or(Query1, Query2) + expect(allAssetsSorted).toBe(true); + } else { + console.warn("No assets returned to verify sorting"); + } + }); + }); + + describe("sorting", () => { + test(".ascending()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + try { + const assets = await Query.ascending(field).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + prev = asset[field]; + return asset[field] >= prev; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".ascending()"); + } + }); + + test(".descending()", async () => { + const Query = Stack.Assets().Query(); + const field = "created_at"; + try { + const assets = await Query.descending(field).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".descending()"); + } + }); + }); + + test(".addParam()", async () => { + const Query = Stack.Assets().Query(); + + try { + const assets = await Query.addParam("include_dimension", "true") .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (~(asset.title === 'image1' || asset.is_dir === true)); - }); - assert.ok(_assets, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".or() - Query Objects"); - assert.end(); + .find(); + expect(assets[0][0].hasOwnProperty("dimension")).toBeTruthy(); + } catch (err) { + console.error("Error:", err); + fail(".addParam()"); + } + }); + + describe("comparison", () => { + describe(".lessThan()", () => { + const field = "file_size"; + const value = 5122; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.lessThan(field, value).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with file_size less than the specified value", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset[field] < value + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify lessThan condition"); + } + }); + }); + + describe(".lessThanOrEqualTo()", () => { + const field = "file_size"; + const value = 5122; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.lessThanOrEqualTo(field, value).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with file_size less than or equal to the specified value", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset[field] <= value + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn( + "No assets returned to verify lessThanOrEqualTo condition" + ); + } + }); + }); + + test(".greaterThan()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; + try { + const assets = await Query.greaterThan("file_size", value) + .ascending(field) + .toJSON() + .find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].slice(1).every((asset) => { + const flag = asset[field] > value; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + fail(".greaterThan()"); + } + }); + + test(".greaterThanOrEqualTo()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; + try { + const assets = await Query.greaterThanOrEqualTo("file_size", 5122) + .descending(field) + .toJSON() + .find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] >= value; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".greaterThanOrEqualTo()"); + } + }); + + describe(".notEqualTo()", () => { + const field = "file_size"; + const value = 5122; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.notEqualTo(field, value) + .descending(field) + .toJSON() + .find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with file_size not equal to the specified value", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset[field] !== value + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify notEqualTo condition"); + } + }); + }); + + describe(".where()", () => { + const title = "image1"; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.where("title", title).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return exactly one asset matching the title", async () => { + expect(assets[0].length).toBe(1); + }); + + test("should return only assets with the specified title", async () => { + if (assets && assets.length && assets[0].length) { + const matchingTitle = assets[0].every( + (asset) => asset.title === title + ); + expect(matchingTitle).toBe(true); + } else { + console.warn("No assets returned to verify where condition"); + } + }); + }); + + describe(".equalTo() with boolean values", () => { + describe("when comparing with false", () => { + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.language("en-us") + .equalTo("is_dir", false) + .toJSON() + .find(); }); -}); -test('.and() - Query Objects', function(assert) { - var Query1 = Stack.Assets().Query().where('title', 'image1'); - var Query2 = Stack.Assets().Query().where('is_dir', true); - var Query = Stack.Assets().Query(); - - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, 'asset not present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (~(asset.title === 'image1' && asset.is_dir === true)); - }); - assert.ok(_assets, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Query Objects"); - assert.end(); + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); }); -}); - -test('.and() - Raw queries', function(assert) { - var Query1 = Stack.Assets().Query().where('title', 'image1'); - var Query2 = Stack.Assets().Query().where('is_dir', true); - var Query = Stack.Assets().Query(); - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, 'asset not present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return ((asset.title === 'image1' && asset.is_dir === true)); - }); - assert.ok(_assets, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Raw queries"); - assert.end(); + test("should return exactly 5 assets matching the condition", async () => { + expect(assets[0].length).toBe(5); }); -}); - -// Custom query -test('.query() - Raw query', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .query({ "$or": [{ "title": "image1" }, { "is_dir": "true" }] }) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 1, 'one asset present in resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (asset.title === 'image1' || asset.is_dir === true) - }); - assert.ok(_assets, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".query() - Raw query"); - assert.end(); + test("should return only assets with is_dir set to false", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset.is_dir === false + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify equalTo condition"); + } }); -}); + }); -test('Non reference .tags() ', function(assert) { - var Query = Stack.Assets().Query(), - tags = ["asset3"]; + describe("when comparing with true", () => { + let assets; - Query - .tags(tags) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - assert.equal(assets[0].length, 0, 'Non refernce tags count should be zero'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.equalTo("is_dir", true).toJSON().find(); }); -}); -// tags -test('.tags()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'tags', - tags = ["asset1", "asset2"]; - - Query - .tags(tags) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (Utils.arrayPresentInArray(tags, asset[field])); - }); - assert.equal(_assets, true, 'Tags specified are found in result set'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); - }); -}); - - -// search -test('.search()', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .search('image1') - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, '1 or more asset present in the resultset'); - assert.equal(assets[0].length, 1, '1 asset present in resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".search()"); - assert.end(); - }); -}); - -// regex -test('.regex()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'title', - regex = { - pattern: '^image', - options: 'i' - }, - regexpObj = new RegExp(regex.pattern, regex.options); - - Query - .language('en-us') - .regex(field, regex.pattern, regex.options) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - assert.equal(assets[0].length, 5, '5 assets present in resultset'); - var flag = assets[0].every(function(asset) { - return regexpObj.test(asset[field]); - }); - assert.ok(flag, "regexp satisfied for all the assets in the resultset"); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".regex()"); - assert.end(); - }); -}); - - - -// includeCount -test('.includeCount()', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .includeCount() - .toJSON() - .find() - .then(function success(assets) { - // assert.ok("assets" in result, 'assets key present in the resultset'); - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(assets[1], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeCount()"); - assert.end(); - }); -}); - -// only -test('.only() - Single String Parameter', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .only('title') - .toJSON() - .find() - .then(function success(assets) { - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "uid" in asset && 'url' in asset); - }); - assert.ok(flag, 'assets with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Single String Parameter"); - assert.end(); - }); -}); - -test('.only() - Multiple String Parameter', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .only('BASE', 'title') - .toJSON() - .find() - .then(function success(assets) { - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "uid" in asset && 'url' in asset); - }); - assert.ok(flag, 'assets with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Multiple String Parameter"); - assert.end(); + test("should return an empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBe(0); }); + }); + }); + }); + + describe("Array/Subset Tests", () => { + describe(".containedIn()", () => { + const _in = ["image1", "image2"]; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.containedIn("title", _in).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with titles contained in the specified array", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every((asset) => { + return _in.indexOf(asset["title"]) !== -1; + }); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify containedIn condition"); + } + }); + + test("should include at least one asset with each of the specified titles", async () => { + if (assets && assets.length && assets[0].length) { + // Check if at least one asset exists for each title in the array + const foundTitles = _in.filter((title) => + assets[0].some((asset) => asset.title === title) + ); + expect(foundTitles.length).toBe(_in.length); + } else { + console.warn("No assets returned to verify all titles are present"); + } + }); + }); + + describe(".notContainedIn()", () => { + const _in = ["image1", "image2"]; + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.notContainedIn("title", _in).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with titles not contained in the specified array", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every((asset) => { + return _in.indexOf(asset["title"]) === -1; + }); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify notContainedIn condition"); + } + }); + + test("should not include any assets with the specified titles", async () => { + if (assets && assets.length && assets[0].length) { + const foundForbiddenTitles = assets[0].filter((asset) => + _in.includes(asset.title) + ); + expect(foundForbiddenTitles.length).toBe(0); + } else { + console.warn("No assets returned to verify excluded titles"); + } + }); + }); + }); + + describe("Element Existence Tests", () => { + test(".exists()", async () => { + const Query = Stack.Assets().Query(); + const queryField = "is_dir"; + const field = "updated_at"; + try { + const assets = await Query.exists(queryField).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".exists()"); + } + }); + + test(".notExists()", async () => { + const Query = Stack.Assets().Query(); + const queryField = "is_dir"; + const field = "updated_at"; + try { + const assets = await Query.notExists(queryField).toJSON().find(); + + expect(assets[0].length).toBeFalsy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + return asset[field] <= prev; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".notExists()"); + } + }); + }); + + describe("Pagination Tests", () => { + test(".skip()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + try { + const allassets = await Query.toJSON().find(); + const assets = await Stack.Assets().Query().skip(1).toJSON().find(); + + expect(assets[0].length >= 2).toBeTruthy(); + expect(allassets[0].slice(1)).toEqual(assets[0]); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".skip()"); + } + }); + + test(".limit()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + try { + const allassets = await Query.toJSON().find(); + const assets = await Stack.Assets().Query().limit(2).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + expect(allassets[0].slice(0, 2)).toEqual(assets[0]); + + if (assets && assets.length && assets[0] && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + } catch (err) { + console.error("Error:", err); + fail(".limit()"); + } + }); + + test(".count()", async () => { + const Query = Stack.Assets().Query(); + try { + const count = await Query.count().toJSON().find(); + expect(count).toBeTruthy(); + } catch (err) { + console.error("Error:", err); + fail(".count()"); + } + }); + }); + + describe("Logical Operators Tests", () => { + describe(".or() - Query Objects", () => { + let assets; + const title = "image1"; + const isDir = true; + + beforeAll(async () => { + const Query1 = Stack.Assets().Query().where("title", title); + const Query2 = Stack.Assets().Query().where("is_dir", isDir); + const Query = Stack.Assets().Query(); + assets = await Query.or(Query1, Query2).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets matching at least one of the specified conditions", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset.title === title || asset.is_dir === isDir + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify OR condition"); + } + }); + + test("should include at least one asset matching the title condition", async () => { + if (assets && assets.length && assets[0].length) { + const anyAssetMatchesTitleCondition = assets[0].some( + (asset) => asset.title === title + ); + expect(anyAssetMatchesTitleCondition).toBe(true); + } else { + console.warn("No assets returned to verify first condition"); + } + }); + }); + + describe(".and() - Query Objects", () => { + let assets; + const title = "image1"; + const isDir = true; + + beforeAll(async () => { + const Query1 = Stack.Assets().Query().where("title", title); + const Query2 = Stack.Assets().Query().where("is_dir", isDir); + const Query = Stack.Assets().Query(); + assets = await Query.and(Query1, Query2).toJSON().find(); + }); + + test("should return an empty array when conditions cannot be satisfied simultaneously", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeFalsy(); + }); + + test("should verify that no assets match both conditions", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset.title === title && asset.is_dir === isDir + ); + expect(allAssetsMatchCondition).toBe(true); + } + }); + }); + + describe(".query() - Raw query", () => { + let assets; + const title = "image2"; + const isDir = true; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.query({ + $or: [{ title: title }, { is_dir: isDir }], + }) + .toJSON() + .find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets matching at least one of the specified conditions", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsMatchCondition = assets[0].every( + (asset) => asset.title === title || asset.is_dir === isDir + ); + expect(allAssetsMatchCondition).toBe(true); + } else { + console.warn("No assets returned to verify raw query conditions"); + } + }); + + test("should include at least one asset matching the title condition", async () => { + if (assets && assets.length && assets[0].length) { + const anyAssetMatchesTitleCondition = assets[0].some( + (asset) => asset.title === title + ); + expect(anyAssetMatchesTitleCondition).toBe(true); + } else { + console.warn("No assets returned to verify first condition"); + } + }); + }); + }); + + describe("Tags Tests", () => { + describe(".tags() - empty results", () => { + let assets; + const tags = ["asset3"]; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.tags(tags).toJSON().find(); + }); + + test("should return a properly structured response", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets.length).toBeGreaterThanOrEqual(1); + }); + + test("should return an empty array when no assets match the tags", async () => { + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBe(0); + }); + }); + + describe(".tags() - with results", () => { + let assets; + const field = "tags"; + const tags = ["asset1", "asset2"]; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.tags(tags).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets.length).toBeGreaterThanOrEqual(1); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with at least one matching tag", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveMatchingTags = assets[0].every((asset) => { + return Utils.arrayPresentInArray(tags, asset[field]); + }); + expect(allAssetsHaveMatchingTags).toBe(true); + } else { + console.warn("No assets returned to verify tags"); + } + }); + + test("should include assets with tags that overlap with the specified tags", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveOverlappingTags = assets[0].every((asset) => { + // Check that asset tags overlap with requested tags + return asset[field].some((tag) => tags.includes(tag)); + }); + expect(allAssetsHaveOverlappingTags).toBe(true); + } else { + console.warn("No assets returned to verify tag overlap"); + } + }); + }); + }); + + describe("Search Tests", () => { + describe(".search()", () => { + let assets; + const searchTerm = "image1"; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.toJSON().search(searchTerm).find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return assets matching the search term", async () => { + if (assets && assets.length && assets[0].length) { + // Verify that each asset contains the search term in some field + // This is a simplified check since search can match across multiple fields + const anyAssetMatchesSearchTerm = assets[0].some( + (asset) => + asset.title.includes(searchTerm) || + (asset.description && asset.description.includes(searchTerm)) + ); + expect(anyAssetMatchesSearchTerm).toBe(true); + } else { + console.warn("No assets returned to verify search results"); + } + }); + }); + + describe(".regex()", () => { + let assets; + const field = "title"; + const regex = { + pattern: "^image", + options: "i", + }; + const regexpObj = new RegExp(regex.pattern, regex.options); + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.regex(field, regex.pattern, regex.options) + .toJSON() + .find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets.length).toBeGreaterThanOrEqual(1); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should return only assets with titles matching the regex pattern", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsTitlesMatchRegex = assets[0].every((asset) => { + return regexpObj.test(asset[field]); + }); + expect(allAssetsTitlesMatchRegex).toBe(true); + } else { + console.warn("No assets returned to verify regex match"); + } + }); + + test('should include assets whose titles start with "image"', async () => { + if (assets && assets.length && assets[0].length) { + const allTitlesStartWithImage = assets[0].every((asset) => + asset.title.toLowerCase().startsWith("image") + ); + expect(allTitlesStartWithImage).toBe(true); + } else { + console.warn("No assets returned to verify specific regex pattern"); + } + }); + }); + }); + + describe("Include Options", () => { + describe(".includeCount()", () => { + let assets; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.includeCount().toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should include count information in the result", async () => { + expect(assets[1]).toBeDefined(); + expect(assets[1]).toBeTruthy(); + }); + + test("should return count as a number", async () => { + expect(typeof assets[1]).toBe("number"); + }); + + test("should return count equal to the number of returned assets", async () => { + expect(assets[1]).toBeGreaterThanOrEqual(assets[0].length); + }); + }); + }); + + describe("Field Projections", () => { + describe(".only() - Single String Parameter", () => { + let assets; + const selectedField = "title"; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.only(selectedField).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should include the selected field in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveSelectedField = assets[0].every( + (asset) => selectedField in asset + ); + expect(allAssetsHaveSelectedField).toBe(true); + } else { + console.warn("No assets returned to verify field projection"); + } + }); + + test("should include system fields along with the selected field", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveRequiredFields = assets[0].every( + (asset) => "title" in asset && "uid" in asset && "url" in asset + ); + expect(allAssetsHaveRequiredFields).toBe(true); + } else { + console.warn("No assets returned to verify system fields"); + } + }); + + test("should limit the total number of fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveLimitedFields = assets[0].every( + (asset) => Object.keys(asset).length === 5 + ); + expect(allAssetsHaveLimitedFields).toBe(true); + } else { + console.warn("No assets returned to verify field count"); + } + }); + }); + + describe(".only() - Multiple String Parameters", () => { + let assets; + const selectedFields = ["BASE", "title"]; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.only(...selectedFields) + .toJSON() + .find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should include the title field in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveTitle = assets[0].every( + (asset) => "title" in asset + ); + expect(allAssetsHaveTitle).toBe(true); + } else { + console.warn("No assets returned to verify field projection"); + } + }); + + test("should include system fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveSystemFields = assets[0].every( + (asset) => "uid" in asset && "url" in asset + ); + expect(allAssetsHaveSystemFields).toBe(true); + } else { + console.warn("No assets returned to verify system fields"); + } + }); + + test("should limit the total number of fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveLimitedFields = assets[0].every( + (asset) => Object.keys(asset).length === 5 + ); + expect(allAssetsHaveLimitedFields).toBe(true); + } else { + console.warn("No assets returned to verify field count"); + } + }); + }); + + describe(".only() - Array Parameter", () => { + let assets; + const selectedFields = ["title", "filename"]; + + beforeAll(async () => { + const Query = Stack.Assets().Query(); + assets = await Query.only(selectedFields).toJSON().find(); + }); + + test("should return a non-empty array of assets", async () => { + expect(assets).toBeDefined(); + expect(Array.isArray(assets)).toBe(true); + expect(assets[0]).toBeDefined(); + expect(assets[0].length).toBeTruthy(); + }); + + test("should include all the selected fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveSelectedFields = assets[0].every((asset) => + selectedFields.every((field) => field in asset) + ); + expect(allAssetsHaveSelectedFields).toBe(true); + } else { + console.warn("No assets returned to verify field projection"); + } + }); + + test("should include system fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveSystemFields = assets[0].every( + (asset) => "uid" in asset && "url" in asset + ); + expect(allAssetsHaveSystemFields).toBe(true); + } else { + console.warn("No assets returned to verify system fields"); + } + }); + + test("should limit the total number of fields in each asset", async () => { + if (assets && assets.length && assets[0].length) { + const allAssetsHaveLimitedFields = assets[0].every( + (asset) => Object.keys(asset).length === 5 + ); + expect(allAssetsHaveLimitedFields).toBe(true); + } else { + console.warn("No assets returned to verify field count"); + } + }); + }); + }); }); - -test('.only() - Array Parameter', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .only(['title', 'filename']) - .toJSON() - .find() - .then(function success(assets) { - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "filename" in asset && "uid" in asset && 'url' in asset); - }); - assert.ok(flag, 'assets with the field title,url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Array Parameter"); - assert.end(); - }); -}); \ No newline at end of file diff --git a/test/asset/find.js b/test/asset/find.js index 3acca3e9..ea2aee3c 100755 --- a/test/asset/find.js +++ b/test/asset/find.js @@ -1,817 +1,582 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -var test = require('tape'); -var Contentstack = require('../../dist/node/contentstack.js'); -var init = require('../config.js'); -var Utils = require('../entry/utils.js') -var Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); +const Utils = require("../entry/utils.js"); + +let Stack; + +describe("Contentstack Asset Tests", () => { + // Initialize the Contentstack Stack Instance + beforeAll(() => { + return new Promise((resolve) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(resolve, 1000); + }); + }); + + describe("Language and Fallback Tests", () => { + test("default .find() No fallback", async () => { + const _in = ["ja-jp"]; + + const assets = await Stack.Assets() + .Query() + .language("ja-jp") + .toJSON() + .find(); + expect(assets[0].length).toBeTruthy(); + expect(assets[1]).toBeFalsy(); -test('default .find() No fallback', function(assert) { - var _in = ['ja-jp'] - Stack.Assets().Query().language('ja-jp').toJSON().find() - .then((assets) => { - assert.ok(assets[0].length, 'Assets present in the resultset'); - assert.notok(assets[1], 'Count should not be present'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['publish_details']['locale']) != -1); - }); - assert.equal(_assets, true, "Publish content fallback" ); - } - assert.end(); - }).catch((error) => { - assert.fail("asset default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('default .find() fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.Assets().Query().language('ja-jp').includeFallback().toJSON().find() - .then((assets) => { - assert.ok(assets[0].length, 'Assets present in the resultset'); - assert.notok(assets[1], 'Count should not be present'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['publish_details']['locale']) != -1); - }); - assert.equal(_assets, true, "Publish content fallback" ); - } - assert.end(); - }).catch((error) => { - assert.fail("asset default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('default .find()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - Query - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'Assets present in the resultset'); - assert.notok(assets[1], 'Count should not be present'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - prev = asset[field]; - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("asset default .find()"); - assert.end(); + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return _in.indexOf(asset["publish_details"]["locale"]) !== -1; }); -}); + expect(_assets).toBe(true); + } + }); -/*! - * SORTING - * !*/ -test('.ascending()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; + test("default .find() fallback", async () => { + const _in = ["ja-jp", "en-us"]; - Query - .ascending(field) + const assets = await Stack.Assets() + .Query() + .language("ja-jp") + .includeFallback() .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - prev = asset[field]; - return (asset[field] >= prev); - }); - assert.equal(_assets, true, "assets sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".ascending()"); - assert.end(); - }); -}); + .find(); -test('.descending()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'created_at'; - Query - .descending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".descending()"); - assert.end(); + expect(assets[0].length).toBeTruthy(); + expect(assets[1]).toBeFalsy(); + + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return _in.indexOf(asset["publish_details"]["locale"]) !== -1; }); -}); + expect(_assets).toBe(true); + } + }); + }); + + test("default .find()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + const assets = await Query.toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + expect(assets[1]).toBeFalsy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + }); + + describe("Sorting", () => { + test(".ascending()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + + const assets = await Query.ascending(field).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] >= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + }); -// addparam -test('.addParam()', function(assert) { - var Query = Stack.Assets().Query(); - Query - .addParam('include_dimension', 'true') - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0][0].hasOwnProperty('dimension'), 'dimension present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".addParam()"); - assert.end(); + test(".descending()", async () => { + const Query = Stack.Assets().Query(); + const field = "created_at"; + + const assets = await Query.descending(field).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); + }); + describe("Params", () => { + test(".addParam()", async () => { + const Query = Stack.Assets().Query(); -/*! - * COMPARISION - * !*/ -test('.lessThan()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; - Query - .lessThan('file_size', value) + const assets = await Query.addParam("include_dimension", "true") .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 1, '1 asset present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].slice(1).every(function(asset) { - var flag = (asset[field] < value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error('Error : ', err); - assert.fail(".lessThan()"); - assert.end(); + .find(); + expect(assets[0][0].hasOwnProperty("dimension")).toBeTruthy(); + }); + }); + + describe("Comparison", () => { + test(".lessThan()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; + + const assets = await Query.lessThan("file_size", value).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].slice(1).every((asset) => { + const flag = asset[field] < value; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); + + test(".lessThanOrEqualTo()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; -test('.lessThanOrEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - Query - .lessThanOrEqualTo('file_size', 5122) + const assets = await Query.lessThanOrEqualTo("file_size", 5122) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 2, 'two assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThanOrEqualTo()"); - assert.end(); - }).catch(function(err) { - console.log("error is this: ", err); + .find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); -test('.greaterThan()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; + test(".greaterThan()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; - Query - .greaterThan('file_size', value) + const assets = await Query.greaterThan("file_size", value) .ascending(field) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 3, 'three assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].slice(1).every(function(asset) { - var flag = (asset[field] > value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error() { - assert.fail(".greaterThan()"); - assert.end(); - }); -}); + .find(); -test('.greaterThanOrEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; + expect(assets[0].length).toBeTruthy(); - Query - .greaterThanOrEqualTo('file_size', 5122) - .descending(field) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 4, 'four assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] >= value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThanOrEqualTo()"); - assert.end(); + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].slice(1).every((asset) => { + const flag = asset[field] > value; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); -test('.notEqualTo()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'file_size', - value = 5122; + test(".greaterThanOrEqualTo()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; - Query - .notEqualTo('file_size', value) + const assets = await Query.greaterThanOrEqualTo("file_size", value) .descending(field) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] != value); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notEqualTo()"); - assert.end(); - }); -}); + .find(); -test('.where()', function(assert) { - var Query = Stack.Assets().Query(); - Query - .where('title', "image1") - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 1, 'one asset present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where()"); - assert.end(); - }); -}); + expect(assets[0].length).toBeTruthy(); + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] >= value; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + }); -test('.equalTo() compare boolean value (true)', function(assert) { - var Query = Stack.Assets().Query(); + test(".notEqualTo()", async () => { + const Query = Stack.Assets().Query(); + const field = "file_size"; + const value = 5122; - Query - .language('en-us') - .equalTo('is_dir', false) + const assets = await Query.notEqualTo("file_size", value) + .descending(field) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.equal(assets[0].length, 5, ' five asset present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where()"); - assert.end(); - }); -}); + .find(); -test('.equalTo() compare boolean value (false)', function(assert) { - var Query = Stack.Assets().Query(); - Query - .equalTo('is_dir', true) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, 'assets not present in the resultset'); - assert.equal(assets[0].length, 0, ' three assets present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where() boolean value having false"); - assert.end(); + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] != value; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); -/*! - * Array/Subset - * !*/ + test(".where()", async () => { + const Query = Stack.Assets().Query(); -test('.containedIn()', function(assert) { - var Query = Stack.Assets().Query(), - _in = ["image1", "image2"], - field = 'updated_at'; + const assets = await Query.where("title", "image1").toJSON().find(); - Query - .containedIn('title', _in) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(assets[0].length, 2, 'two assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (_in.indexOf(asset['title']) != -1); - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".containedIn()"); - assert.end(); - }); -}); + expect(assets[0].length).toBeTruthy(); + expect(assets[0].length).toBe(1); + }); -test('.notContainedIn()', function(assert) { - var Query = Stack.Assets().Query(), - _in = ["image1", "image2"]; + test(".equalTo() compare boolean value (true)", async () => { + const Query = Stack.Assets().Query(); - Query - .notContainedIn('title', _in) + const assets = await Query.language("en-us") + .equalTo("is_dir", false) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, ' Assets present in the resultset'); - assert.ok(assets[0].length, 3, 'three assets present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notContainedIn()"); - assert.end(); - }); -}); + .find(); + expect(assets[0].length).toBeTruthy(); + expect(assets[0].length).toBe(5); + }); -/*! - *Element(exists) - * !*/ + test(".equalTo() compare boolean value (false)", async () => { + const Query = Stack.Assets().Query(); -test('.exists()', function(assert) { - var Query = Stack.Assets().Query(), - queryField = "is_dir", - field = 'updated_at'; + const assets = await Query.equalTo("is_dir", true).toJSON().find(); - Query - .exists(queryField) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".exists()"); - assert.end(); - }); -}); + expect(assets[0].length).toBeFalsy(); + expect(assets[0].length).toBe(0); + }); + }); -test('.notExists()', function(assert) { - var Query = Stack.Assets().Query(), - queryField = "is_dir", - field = 'updated_at'; + describe("Array/Subset Tests", () => { + test(".containedIn()", async () => { + const Query = Stack.Assets().Query(); + const _in = ["image1", "image2"]; + const field = "updated_at"; - Query - .notExists(queryField) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, 'No asset present in the resultset'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notExists()"); - assert.end(); + const assets = await Query.containedIn("title", _in).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return _in.indexOf(asset["title"]) != -1; }); -}); + expect(_assets).toBe(true); + } + }); + test(".notContainedIn()", async () => { + const Query = Stack.Assets().Query(); + const _in = ["image1", "image2"]; -// Pagination -test('.skip()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; + const assets = await Query.notContainedIn("title", _in).toJSON().find(); - Query - .toJSON() - .find() - .then(function success(allassets) { - Stack - .Assets() - .Query() - .skip(1) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets[0].length >= 2), '2 or more assets present in the resultset'); - assert.deepEqual(allassets[0].slice(1), assets[0], 'All elements matched.'); - if (assets && assets.length && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".skip()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".skip()"); - assert.end(); - }); -}); + expect(assets[0].length).toBeTruthy(); + }); + }); -test('.limit()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; + describe("Element Existence Tests", () => { + test(".exists()", async () => { + const Query = Stack.Assets().Query(); + const queryField = "is_dir"; + const field = "updated_at"; - Query - .toJSON() - .find() - .then(function success(allassets) { - Stack - .Assets() - .Query() - .limit(2) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.deepEqual(allassets[0].slice(0, 2), assets[0], 'All elements matched.'); - if (assets && assets.length && assets[0] && assets[0].length) { - var prev = assets[0][0][field]; - var _assets = assets[0].every(function(asset) { - var flag = (asset[field] <= prev); - prev = asset[field]; - return flag; - }); - assert.equal(_assets, true, "assets sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); -}); + const assets = await Query.exists(queryField).toJSON().find(); -test('.count()', function(assert) { - var Query = Stack.Assets().Query(); + expect(assets[0].length).toBeTruthy(); - Query - .count() - .toJSON() - .find() - .then(function success(count) { - // assert.ok("assets" in result, 'assets key present in the resultset'); - assert.ok(count, 'assets present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".count()"); - assert.end(); + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; }); -}); + expect(_assets).toBe(true); + } + }); + test(".notExists()", async () => { + const Query = Stack.Assets().Query(); + const queryField = "is_dir"; + const field = "updated_at"; -// Logical -test('.or() - Query Objects', function(assert) { - var Query1 = Stack.Assets().Query().where('title', 'image1'); - var Query2 = Stack.Assets().Query().where('is_dir', true); - var Query = Stack.Assets().Query(); + const assets = await Query.notExists(queryField).toJSON().find(); - Query - .or(Query1, Query2) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(assets[0].length, 1, 'one asset present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (~(asset.title === 'source1' || asset.is_dir === true)); - }); - assert.ok(_assets, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".or() - Query Objects"); - assert.end(); + expect(assets[0].length).toBeFalsy(); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + return asset[field] <= prev; }); -}); + expect(_assets).toBe(true); + } + }); + }); + + describe("Pagination Tests", () => { + test(".skip()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + + const allassets = await Query.toJSON().find(); + const assets = await Stack.Assets().Query().skip(1).toJSON().find(); + + expect(assets[0].length >= 2).toBeTruthy(); + expect(allassets[0].slice(1)).toEqual(assets[0]); + + if (assets && assets.length && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + }); + + test(".limit()", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + + const allassets = await Query.toJSON().find(); + const assets = await Stack.Assets().Query().limit(2).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + expect(allassets[0].slice(0, 2)).toEqual(assets[0]); + + if (assets && assets.length && assets[0] && assets[0].length) { + let prev = assets[0][0][field]; + const _assets = assets[0].every((asset) => { + const flag = asset[field] <= prev; + prev = asset[field]; + return flag; + }); + expect(_assets).toBe(true); + } + }); -test('.and() - Query Objects', function(assert) { - var Query1 = Stack.Assets().Query().where('title', 'image1'); - var Query2 = Stack.Assets().Query().where('is_dir', true); - var Query = Stack.Assets().Query(); + test(".count()", async () => { + const Query = Stack.Assets().Query(); - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(assets) { - assert.notok(assets[0].length, ' asset not present in the resultset'); - if (assets && assets.length && assets[0].length) { - // console.log("\n\n\n\n",JSON.stringify(assets)); - var _assets = assets[0].every(function(asset) { - return (~(asset.title === 'image1' && asset.is_dir === true)); - }); - assert.ok(_assets, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Query Objects"); - assert.end(); - }); -}); + const count = await Query.count().toJSON().find(); + expect(count).toBeTruthy(); + }); + }); -// Custom query -test('.query() - Raw query', function(assert) { - var Query = Stack.Assets().Query(); + describe("Logical Operators Tests", () => { + test(".or() - Query Objects", async () => { + const Query1 = Stack.Assets().Query().where("title", "image1"); + const Query2 = Stack.Assets().Query().where("is_dir", true); + const Query = Stack.Assets().Query(); - Query - .query({ "$or": [{ "title": "image2" }, { "is_dir": "true" }] }) - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(assets[0].length, 1, 'one asset present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (asset.title === 'image2' || asset.is_dir === false) - }); - assert.ok(_assets, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".query() - Raw query"); - assert.end(); + const assets = await Query.or(Query1, Query2).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return ~(asset.title === "source1" || asset.is_dir === true); }); -}); + expect(_assets).toBeTruthy(); + } + }); + test(".and() - Query Objects", async () => { + const Query1 = Stack.Assets().Query().where("title", "image1"); + const Query2 = Stack.Assets().Query().where("is_dir", true); + const Query = Stack.Assets().Query(); -test('.tags()', function(assert) { - var Query = Stack.Assets().Query(), - tags = ["asset3"]; + const assets = await Query.and(Query1, Query2).toJSON().find(); - Query - .tags(tags) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - assert.equal(assets[0].length, 0, 'Non refernce tags count should be zero'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); - }); -}); -// tags -test('.tags()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'tags', - tags = ["asset1", "asset2"]; - - Query - .tags(tags) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - if (assets && assets.length && assets[0].length) { - var _assets = assets[0].every(function(asset) { - return (Utils.arrayPresentInArray(tags, asset[field])); - }); - assert.equal(_assets, true, 'Tags specified are found in result set'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); + expect(assets[0].length).toBeFalsy(); + + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return ~(asset.title === "image1" && asset.is_dir === true); }); -}); + expect(_assets).toBeTruthy(); + } + }); + test(".query() - Raw query", async () => { + const Query = Stack.Assets().Query(); -// search -test('.search()', function(assert) { - var Query = Stack.Assets().Query(); - Query + const assets = await Query.query({ + $or: [{ title: "image2" }, { is_dir: "true" }], + }) .toJSON() - .search('image1') - .find() - .then(function success(assets) { - assert.ok(assets[0].length, '1 asset present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".search()"); - assert.end(); - }); -}); + .find(); -// regex -test('.regex()', function(assert) { - var Query = Stack.Assets().Query(), - field = 'title', - regex = { - pattern: '^image', - options: 'i' - }, - regexpObj = new RegExp(regex.pattern, regex.options); - - Query - .regex(field, regex.pattern, regex.options) - .toJSON() - .find() - .then(function success(assets) { - assert.ok((assets.length >= 1), '1 or more asset/assets present in the resultset'); - var flag = assets[0].every(function(asset) { - return regexpObj.test(asset[field]); - }); - assert.ok(flag, "regexp satisfied for all the assets in the resultset"); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".regex()"); - assert.end(); + expect(assets[0].length).toBeTruthy(); + + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return asset.title === "image2" || asset.is_dir === false; }); -}); + expect(_assets).toBeTruthy(); + } + }); + }); + describe("Tags Tests", () => { + test(".tags() - empty results", async () => { + const Query = Stack.Assets().Query(); + const tags = ["asset3"]; -// includeCount -test('.includeCount()', function(assert) { - var Query = Stack.Assets().Query(); + const assets = await Query.tags(tags).toJSON().find(); - Query - .includeCount() - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - assert.ok(assets[1], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeCount()"); - assert.end(); - }); -}); + expect(assets.length >= 1).toBeTruthy(); + if (assets && assets.length && assets[0].length) { + expect(assets[0].length).toBe(0); + } + }); -// only -test('.only() - Single String Parameter', function(assert) { - var Query = Stack.Assets().Query(); + test(".tags() - with results", async () => { + const Query = Stack.Assets().Query(); + const field = "tags"; + const tags = ["asset1", "asset2"]; - Query - .only('title') - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "uid" in asset && 'url' in asset); - }); - assert.ok(flag, 'assets with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Single String Parameter"); - assert.end(); - }); -}); + const assets = await Query.tags(tags).toJSON().find(); -test('.only() - Multiple String Parameter', function(assert) { - var Query = Stack.Assets().Query(); + expect(assets.length >= 1).toBeTruthy(); - Query - .only('BASE', 'title') - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "uid" in asset && 'url' in asset); - }); - assert.ok(flag, 'assets with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Multiple String Parameter"); - assert.end(); + if (assets && assets.length && assets[0].length) { + const _assets = assets[0].every((asset) => { + return Utils.arrayPresentInArray(tags, asset[field]); }); -}); - -test('.only() - Array Parameter', function(assert) { - var Query = Stack.Assets().Query(); - - Query - .only(['title', 'filename']) + expect(_assets).toBe(true); + } + }); + }); + + describe("Search Tests", () => { + test(".search()", async () => { + const Query = Stack.Assets().Query(); + + const assets = await Query.toJSON().search("image1").find(); + expect(assets[0].length).toBeTruthy(); + }); + + test(".regex()", async () => { + const Query = Stack.Assets().Query(); + const field = "title"; + const regex = { + pattern: "^image", + options: "i", + }; + const regexpObj = new RegExp(regex.pattern, regex.options); + + const assets = await Query.regex(field, regex.pattern, regex.options) .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'assets present in the resultset'); - var flag = assets[0].every(function(asset) { - return (asset && Object.keys(asset).length === 5 && "title" in asset && "filename" in asset && "uid" in asset && "url" in asset); - }); - assert.ok(flag, 'assets with the field title,filename in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Array Parameter"); - assert.end(); - }); -}); \ No newline at end of file + .find(); + + expect(assets.length >= 1).toBeTruthy(); + + const flag = assets[0].every((asset) => { + return regexpObj.test(asset[field]); + }); + expect(flag).toBeTruthy(); + }); + }); + + describe("Include Options", () => { + test(".includeCount()", async () => { + const Query = Stack.Assets().Query(); + + const assets = await Query.includeCount().toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + expect(assets[1]).toBeTruthy(); + }); + }); + + describe("Field Projections", () => { + test(".only() - Single String Parameter", async () => { + const Query = Stack.Assets().Query(); + + const assets = await Query.only("title").toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + const flag = assets[0].every((asset) => { + return ( + asset && + Object.keys(asset).length === 5 && + "title" in asset && + "uid" in asset && + "url" in asset + ); + }); + expect(flag).toBeTruthy(); + }); + + test(".only() - Multiple String Parameter", async () => { + const Query = Stack.Assets().Query(); + + const assets = await Query.only("BASE", "title").toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + const flag = assets[0].every((asset) => { + return ( + asset && + Object.keys(asset).length === 5 && + "title" in asset && + "uid" in asset && + "url" in asset + ); + }); + expect(flag).toBeTruthy(); + }); + + test(".only() - Array Parameter", async () => { + const Query = Stack.Assets().Query(); + + const assets = await Query.only(["title", "filename"]).toJSON().find(); + + expect(assets[0].length).toBeTruthy(); + + const flag = assets[0].every((asset) => { + return ( + asset && + Object.keys(asset).length === 5 && + "title" in asset && + "filename" in asset && + "uid" in asset && + "url" in asset + ); + }); + expect(flag).toBeTruthy(); + }); + }); +}); diff --git a/test/asset/image-transformation.js b/test/asset/image-transformation.js index bb761cae..87ac2861 100755 --- a/test/asset/image-transformation.js +++ b/test/asset/image-transformation.js @@ -2,7 +2,6 @@ /* * Module Dependencies. */ -const test = require('tape'); const Contentstack = require('../../dist/node/contentstack.js'); const init = require('./../config.js'); const Utils = require('./../entry/utils.js'); @@ -11,91 +10,145 @@ const Regexp = new RegExp('\\\?', 'g'); let Stack; let Asset; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - -test('Get All Assets', function(assert) { - Stack - .Assets() - .Query() - .toJSON() - .find() - .then(function success(assets) { - assert.ok(assets[0].length, 'Assets present in the resultset'); - Asset = assets[0][0]; - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("asset default .find()"); - assert.end(); - }); -}); - -test('Valid URL: single parameter testing', function(assert) { + +describe('Image Transformation Tests', () => { + // Setup - runs before all tests + beforeAll(done => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(done, 1000); + }); + + // Get assets for testing + describe('Get All Assets', () => { + beforeAll(async () => { + try { + const assets = await Stack.Assets().Query().toJSON().find(); + Asset = assets[0][0]; + } catch (error) { + console.error("error:", error); + throw new Error("Failed to get assets"); + } + }); + + test('Should have assets in the resultset', () => { + expect(Asset).toBeDefined(); + }); + }); + + describe('Valid URL: single parameter testing', () => { + let Image; const Params = { - quality: 50 - } - const URL = Asset['url']; - const Image = Stack.imageTransform(URL, Params); - console.log("URL : ", Image, Image.match(Regexp)); - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - for (var key in Params) { - assert.ok((Image.indexOf('?' + key + '=' + Params[key]) !== -1), "Supplied parameter " + key + " found"); - } - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - assert.end(); -}); - -test('Valid URL: multiple parameter testing', function(assert) { + quality: 50 + }; + + beforeAll(() => { + const URL = Asset['url']; + Image = Stack.imageTransform(URL, Params); + }); + + test('Should generate valid URL', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + + test('Should include quality parameter', () => { + expect(Image.includes('?quality=50')).toBe(true); + }); + + test('Should verify URL is valid again', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + }); + + describe('Valid URL: multiple parameter testing', () => { + let Image; const Params = { - quality: 50, - auto: 'webp', - format: 'jpg' - } - const URL = Asset['url']; - const Image = Stack.imageTransform(URL, Params); - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - for (var key in Params) { - assert.ok((Image.indexOf(key + '=' + Params[key]) !== -1), "Supplied parameter " + key + " found"); - } - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - assert.end(); -}); - -test('Invalid URL: single parameter testing', function(assert) { + quality: 50, + auto: 'webp', + format: 'jpg' + }; + + beforeAll(() => { + const URL = Asset['url']; + Image = Stack.imageTransform(URL, Params); + }); + + test('Should generate valid URL', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + + test('Should include quality parameter', () => { + expect(Image.includes('quality=50')).toBe(true); + }); + + test('Should include auto parameter', () => { + expect(Image.includes('auto=webp')).toBe(true); + }); + + test('Should include format parameter', () => { + expect(Image.includes('format=jpg')).toBe(true); + }); + + test('Should verify URL is valid again', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + }); + + describe('Invalid URL: single parameter testing', () => { + let Image; const Params = { - quality: 50 - } - const URL = Asset['url'] + '?'; - const Image = Stack.imageTransform(URL, Params); - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - for (var key in Params) { - assert.ok((Image.indexOf(key + '=' + Params[key]) !== -1), "Supplied parameter " + key + " found"); - } - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - assert.end(); -}); - -test('Invalid URL: multiple parameter testing', function(assert) { + quality: 50 + }; + + beforeAll(() => { + const URL = Asset['url'] + '?'; + Image = Stack.imageTransform(URL, Params); + }); + + test('Should generate valid URL', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + + test('Should include quality parameter', () => { + expect(Image.includes('quality=50')).toBe(true); + }); + + test('Should verify URL is valid again', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + }); + + describe('Invalid URL: multiple parameter testing', () => { + let Image; const Params = { - quality: 50, - auto: 'webp', - format: 'jpg' - } - const URL = Asset['url'] + '?'; - const Image = Stack.imageTransform(URL, Params); - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - for (var key in Params) { - assert.ok((Image.indexOf(key + '=' + Params[key]) !== -1), "Supplied parameter " + key + " found"); - } - assert.ok((Image.match(Regexp).length === 1), "Valid URL is generated"); - assert.end(); + quality: 50, + auto: 'webp', + format: 'jpg' + }; + + beforeAll(() => { + const URL = Asset['url'] + '?'; + Image = Stack.imageTransform(URL, Params); + }); + + test('Should generate valid URL', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + + test('Should include quality parameter', () => { + expect(Image.includes('quality=50')).toBe(true); + }); + + test('Should include auto parameter', () => { + expect(Image.includes('auto=webp')).toBe(true); + }); + + test('Should include format parameter', () => { + expect(Image.includes('format=jpg')).toBe(true); + }); + + test('Should verify URL is valid again', () => { + expect(Image.match(Regexp).length).toBe(1); + }); + }); }); \ No newline at end of file diff --git a/test/asset/spread.js b/test/asset/spread.js index a41067b8..6fe9b0d1 100755 --- a/test/asset/spread.js +++ b/test/asset/spread.js @@ -1,95 +1,63 @@ /** * Created by Aamod Pisat on 09-06-2017. */ -'use strict'; +"use strict"; /* * Module Dependencies. */ -var test = require('tape'); -var Contentstack = require('../../dist/node/contentstack.js'); -var init = require('../config.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); -var Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); +let Stack; +describe("Contentstack Asset Tests", () => { + // Initialize the Contentstack Stack Instance + beforeAll(() => { + return new Promise((resolve) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(resolve, 1000); + }); + }); -test('assets as first argument', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; + test("assets as first argument", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; - Query - .limit(1) - .toJSON() - .find() - .spread(function success(assets) { - assert.ok(assets.length, 'assets exists as first parameter'); - if (assets && assets.length) { - var prev = assets[0][field]; - var _assets = assets.every(function(asset) { - prev = asset[field]; - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); - }); -}); + const result = await Query.limit(1).toJSON().find(); -test('with assets and count argument', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - Query - .includeCount() - .toJSON() - .find() - .spread(function success(assets, count) { - assert.ok(assets.length, 'assets exists as first parameter'); - assert.ok(count, 'Count exists as second parameter'); - if (assets && assets.length) { - var prev = assets[0][field]; - var _assets = assets.every(function(asset) { - prev = asset[field]; - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); - }); -}); + const assets = result[0]; // Using array destructuring + + expect(assets.length).toBeTruthy(); + + if (assets && assets.length) { + let prev = assets[0][field]; + const _assets = assets.every((asset) => { + prev = asset[field]; + return asset[field] <= prev; + }); + expect(_assets).toBe(true); + } + }); -test('with assets and count argument', function(assert) { - var Query = Stack.Assets().Query(), - field = 'updated_at'; - Query - .includeCount() - .toJSON() - .find() - .spread(function success(assets, count) { - assert.ok(assets.length, 'assets exists as first parameter'); - assert.ok(count, 'Count exists as second parameter'); - if (assets && assets.length) { - var prev = assets[0][field]; - var _assets = assets.every(function(asset) { - prev = asset[field]; - return (asset[field] <= prev); - }); - assert.equal(_assets, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); - }); -}); \ No newline at end of file + test("with assets and count argument", async () => { + const Query = Stack.Assets().Query(); + const field = "updated_at"; + + const result = await Query.includeCount().toJSON().find(); + + const [assets, count] = result; // Using array destructuring + + expect(assets.length).toBeTruthy(); + expect(count).toBeTruthy(); + + if (assets && assets.length) { + let prev = assets[0][field]; + const _assets = assets.every((asset) => { + prev = asset[field]; + return asset[field] <= prev; + }); + expect(_assets).toBe(true); + } + }); +}); diff --git a/test/config.js b/test/config.js index 69c45db8..0cea9c0c 100755 --- a/test/config.js +++ b/test/config.js @@ -1,5 +1,15 @@ 'use strict'; -require('dotenv').config() +require('dotenv').config(); + +const requiredVars = ['HOST', 'API_KEY', 'DELIVERY_TOKEN', 'ENVIRONMENT']; +const missingVars = requiredVars.filter((key) => !process.env[key]); + +if (missingVars.length > 0) { + const errorMessage = `\x1b[31mError: Missing environment variables - ${missingVars.join(', ')}`; + const error = new Error(errorMessage); + error.stack = error.message; + throw error; +} module.exports = { stack: { 'api_key': process.env.API_KEY, 'delivery_token': process.env.DELIVERY_TOKEN, 'environment': process.env.ENVIRONMENT, }, diff --git a/test/entry/find-result-wrapper.js b/test/entry/find-result-wrapper.js index c6b553f2..a62e73a1 100755 --- a/test/entry/find-result-wrapper.js +++ b/test/entry/find-result-wrapper.js @@ -1,1130 +1,1269 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const test = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const init = require('../config.js'); -const Utils = require('./utils.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); +const Utils = require("./utils.js"); const contentTypes = init.contentTypes; let Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - console.log(init.stack) - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - -test('default .find()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(!entries[1], 'Count should not present in the result'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - prev = entry[field]; - return (entry.updated_at <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("default .find()"); - assert.end(); +let error = null; + +describe("ContentStack SDK Tests", () => { + // Initialize the Contentstack Stack Instance + beforeAll(() => { + return new Promise((resolve) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(resolve, 1000); + }); + }); + + describe("default .find()", () => { + let entries; + const field = "updated_at"; + + // Setup - run the query once for all tests + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.toJSON().find(); + }); + + test("should return a non-empty array of entries", async () => { + expect(entries).toBeDefined(); + expect(Array.isArray(entries)).toBe(true); + expect(entries[0]).toBeDefined(); + expect(entries[0].length).toBeTruthy(); + }); + + test("should not include count when not requested", async () => { + expect(entries[1]).toBeFalsy(); + }); + + test("should return entries sorted by updated_at in descending order by default", async () => { + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + prev = entry[field]; + return entry.updated_at <= prev; }); -}); - -/*! - * SORTING - * !*/ -test('.ascending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .ascending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - prev = entry[field]; - return (entry[field] >= prev); - }); - assert.equal(_entries, true, "entries sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".ascending()"); - assert.end(); + expect(_entries).toBe(true); + } else { + console.warn("Not enough entries returned to verify default sorting"); + } + }); + + test("should have entries with valid structure", async () => { + if (entries && entries.length && entries[0].length) { + const firstEntry = entries[0][0]; + expect(firstEntry).toHaveProperty("uid"); + expect(firstEntry).toHaveProperty("title"); + expect(firstEntry).toHaveProperty("updated_at"); + } else { + console.warn("No entries returned to verify structure"); + } + }); + }); + + describe("sorting", () => { + test(".ascending()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "updated_at"; + + const entries = await Query.ascending(field).toJSON().find(); + + expect(entries[0].length).toBeTruthy(); + + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + prev = entry[field]; + return entry[field] >= prev; }); -}); + expect(_entries).toBe(true); + } + }); -test('.descending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'created_at'; + test(".descending()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "created_at"; - Query - .descending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - prev = entry[field]; - return (entry[field] >= prev); - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".descending()"); - assert.end(); - }); -}); + const entries = await Query.descending(field).toJSON().find(); + expect(entries[0].length).toBeTruthy(); -/*! - * COMPARISION - * !*/ -test('.lessThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - value = 11, - field = 'updated_at'; - Query - .lessThan('num_field', value) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = true; - _entries = entries[0].slice(1).every(function(entry) { - var flag = (entry[field] < value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThan()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + prev = entry[field]; + return entry[field] >= prev; }); -}); - -test('.lessThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'updated_at', - value = 11; - Query - .lessThanOrEqualTo('num_field', value) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThanOrEqualTo()"); - assert.end(); + expect(_entries).toBe(true); + } + }); + }); + + describe("comparison", () => { + test(".lessThan()", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + const value = 11; + const field = "updated_at"; + + const entries = await Query.lessThan("num_field", value).toJSON().find(); + + expect(entries[0].length).toBeTruthy(); + + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].slice(1).every(function (entry) { + const flag = entry[field] < value; + prev = entry[field]; + return flag; }); -}); + expect(_entries).toBe(true); + } + }); + + test(".lessThanOrEqualTo()", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + const field = "updated_at"; + const value = 11; + + const entries = await Query.lessThanOrEqualTo("num_field", value) + .toJSON() + .find(); -test('.greaterThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; + expect(entries[0].length).toBeTruthy(); - Query - .greaterThan('num_field', value) + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] <= prev; + prev = entry[field]; + return flag; + }); + expect(_entries).toBe(true); + } + }); + + test(".greaterThan()", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + const field = "num_field"; + const value = 11; + + const entries = await Query.greaterThan("num_field", value) .ascending(field) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].slice(1).every(function(entry) { - var flag = (entry[field] > value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThan()"); - assert.end(); - }); -}); + .find(); -test('.greaterThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; + expect(entries[0].length).toBeTruthy(); - Query - .greaterThanOrEqualTo('num_field', value) - .descending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] >= value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThanOrEqualTo()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].slice(1).every(function (entry) { + const flag = entry[field] > value; + prev = entry[field]; + return flag; }); -}); - -test('.notEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 6; - - Query - .notEqualTo('num_field', value) + expect(_entries).toBe(true); + } + }); + + test(".greaterThanOrEqualTo()", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + const field = "num_field"; + const value = 11; + + const entries = await Query.greaterThanOrEqualTo("num_field", value) .descending(field) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] != value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notEqualTo()"); - assert.end(); - }); -}); + .find(); -/*! - * Array/Subset - * !*/ + expect(entries[0].length).toBeTruthy(); -test('.containedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2"], - field = 'updated_at'; - - Query - .containedIn('title', _in) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['title']) != -1); - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".containedIn()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] >= value; + prev = entry[field]; + return flag; }); -}); - -test('.notContainedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["sourceddd1", "sourceddddd2"]; - - Query - .notContainedIn('title', _in) + expect(_entries).toBe(true); + } + }); + + test(".notEqualTo()", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + const field = "num_field"; + const value = 6; + + const entries = await Query.notEqualTo("num_field", value) + .descending(field) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'No Entry present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notContainedIn()"); - assert.end(); - }); -}); - - -/*! - *Element(exists) - * !*/ + .find(); -test('.exists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "boolean", - field = 'updated_at'; + expect(entries[0].length).toBeTruthy(); - Query - .exists(queryField) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries should not be present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".exists()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] != value; + prev = entry[field]; + return flag; }); -}); - -test('.notExists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "isspecial", - field = 'updated_at'; + expect(_entries).toBe(true); + } + }); + }); - Query - .notExists(queryField) - .toJSON() - .find() - .then(function success(entries) { - assert.ok("entries" in entries, 'Entries key present in the resultset'); - //assert.notok(entries[0].length, 'No entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notExists()"); - assert.end(); - }); -}); + describe("array/subset", () => { + test(".containedIn()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const _in = ["source1", "source2"]; + const field = "updated_at"; + const entries = await Query.containedIn("title", _in).toJSON().find(); -// Pagination -test('.skip()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; + expect(entries[0].length).toBeTruthy(); - Query - .toJSON() - .find() - .then(function success(allEntries) { - // assert.ok("entries" in allEntries, 'Entries key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .skip(1) - .toJSON() - .find() - .then(function result(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok((entries[0].length >= 2), '2 or more Entries present in the resultset'); - assert.deepEqual(allEntries[0].slice(1), entries[0], 'All elements matched.'); - if (entries && entries.length && entries[0].length) { - allEntries[0] = allEntries[0].slice(1); - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(""); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail("skip()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + const _entries = entries[0].every(function (entry) { + return _in.indexOf(entry["title"]) != -1; }); -}); + expect(_entries).toBe(true); + } + }); -test('.limit()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .toJSON() - .find() - .then(function success(allEntries) { - // assert.ok("entries" in allEntries, 'Entries key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .limit(2) - .toJSON() - .find() - .then(function result(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.deepEqual(allEntries[0].slice(0, 2), entries[0], 'All elements matched.'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); -}); + test(".notContainedIn()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const _in = ["sourceddd1", "sourceddddd2"]; -test('.count()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + const entries = await Query.notContainedIn("title", _in).toJSON().find(); - Query - .count() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0], 'Entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".count()"); - assert.end(); - }); -}); + expect(entries[0].length).toBeTruthy(); + }); + }); + describe("exists", () => { + test(".exists()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const queryField = "boolean"; + const field = "updated_at"; + const entries = await Query.exists(queryField).toJSON().find(); -// Logical -test('.or() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().containedIn('title', ['source1', 'source2']); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); + expect(entries[0].length).toBeTruthy(); - Query - .or(Query1, Query2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (~(entry.title === 'source1' || entry.boolean === true)); - }); - assert.ok(_entries, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".or() - Query Objects"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] <= prev; + prev = entry[field]; + return flag; }); -}); + expect(_entries).toBe(true); + } + }); -test('.and() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().where('title', 'source1'); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); + test(".notExists()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const queryField = "isspecial"; + const field = "updated_at"; - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (~(entry.title === 'source1' || entry.boolean === true)); - }); - assert.ok(_entries, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Query Objects"); - assert.end(); - }); -}); + const entries = await Query.notExists(queryField).toJSON().find(); -test('.and() - Raw queries', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().where('title', 'source1'); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); + expect("entries" in entries).toBeTruthy(); - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (~(entry.title === 'source1' || entry.boolean === true)); - }); - assert.ok(_entries, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Raw queries"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + return entry[field] <= prev; }); -}); + expect(_entries).toBe(true); + } + }); + }); + describe("pagination", () => { + test(".skip()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "updated_at"; -// Custom query -test('.query() - Raw query', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + const allEntries = await Query.toJSON().find(); - Query - .query({ "$or": [{ "title": "source1" }, { "boolean": "true" }] }) + const entries = await Stack.ContentType(contentTypes.source) + .Query() + .skip(1) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (entry.title === 'source1' || entry.boolean === true) - }); - assert.ok(_entries, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".query() - Raw query"); - assert.end(); + .find(); + + expect(entries[0].length).toBeGreaterThanOrEqual(2); + expect(allEntries[0].slice(1)).toEqual(entries[0]); + + if (entries && entries.length && entries[0].length) { + allEntries[0] = allEntries[0].slice(1); + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] <= prev; + prev = entry[field]; + return flag; }); -}); + expect(_entries).toBe(true); + } + }); + test(".limit()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "updated_at"; -// tags -test('.tags()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'tags', - tags = ["tag1", "tag2"]; + const allEntries = await Query.toJSON().find(); - Query - .tags(tags) + const entries = await Stack.ContentType(contentTypes.source) + .Query() + .limit(2) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok((entries.length >= 1), '1 or more Entry/Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (Utils.arrayPresentInArray(tags, entry[field])); - }); - assert.equal(_entries, true, 'Tags specified are found in result set'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); - }); -}); + .find(); + expect(entries[0].length).toBeTruthy(); + expect(allEntries[0].slice(0, 2)).toEqual(entries[0]); -// search -test('.search()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .search('source1') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, '1 or more Entry present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".search()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] <= prev; + prev = entry[field]; + return flag; }); -}); - -// regex -test('.regex()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'title', - regex = { - pattern: '^source', - options: 'i' - }, - regexpObj = new RegExp(regex.pattern, regex.options); - - Query - .regex(field, regex.pattern, regex.options) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok((entries.length >= 1), '1 or more Entry/Entries present in the resultset'); - var flag = entries[0].every(function(entry) { - return regexpObj.test(entry[field]); - }); - assert.ok(flag, "regexp satisfied for all the entries in the resultset"); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".regex()"); - assert.end(); - }); -}); + expect(_entries).toBe(true); + } + }); + + test(".count()", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + + const entries = await Query.count().toJSON().find(); + + expect(entries[0]).toBeTruthy(); + }); + }); + + describe("logical", () => { + describe(".or() - Query Objects", () => { + let entries; + const titles = ["source1", "source2"]; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .containedIn("title", titles); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entries = await Query.or(Query1, Query2).toJSON().find(); + }); + + test("should return a non-empty array of entries", async () => { + expect(entries).toBeDefined(); + expect(Array.isArray(entries)).toBe(true); + expect(entries[0]).toBeDefined(); + expect(entries[0].length).toBeTruthy(); + }); + + test("should return entries matching at least one of the conditions", async () => { + if (entries && entries.length && entries[0].length) { + const allEntriesMatchAnyCondition = entries[0].every( + (entry) => titles.includes(entry.title) || entry.boolean === true + ); + expect(allEntriesMatchAnyCondition).toBe(true); + } else { + console.warn("No entries returned to verify OR condition"); + } + }); + test("should include entries with title in the specified list", async () => { + if (entries && entries.length && entries[0].length) { + const hasEntryWithTitle = entries[0].some((entry) => + titles.includes(entry.title) + ); + expect(hasEntryWithTitle).toBe(true); + } else { + console.warn("No entries returned to verify first condition"); + } + }); -test('find: without fallback', function(assert) { - var _in = ['ja-jp'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .toJSON() - .find() - .then((entries) => { - assert.ok(entries[0].length, 'Entries present in the resultset'); + test("should include entries with boolean field set to true", async () => { if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['publish_details']['locale']) != -1); - }); - assert.equal(_entries, true, "Publish content fallback"); + const hasEntryWithBoolean = entries[0].some( + (entry) => entry.boolean === true + ); + expect(hasEntryWithBoolean).toBe(true); + } else { + console.warn("No entries returned to verify second condition"); } - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('find: fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .includeFallback() - .toJSON() - .find() - .then((entries) => { - assert.ok(entries[0].length, 'Entries present in the resultset'); + }); + }); + + describe(".and() - Query Objects", () => { + let entries; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .where("title", "source1"); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entries = await Query.and(Query1, Query2).toJSON().find(); + }); + + test("should return a non-empty array of entries", async () => { + expect(entries).toBeDefined(); + expect(Array.isArray(entries)).toBe(true); + expect(entries[0]).toBeDefined(); + expect(entries[0].length).toBeTruthy(); + }); + + test("should return only entries matching all specified conditions", async () => { if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['publish_details']['locale']) != -1); - }); - assert.equal(_entries, true, "Publish content fallback"); + const allEntriesMatchAllConditions = entries[0].every( + (entry) => entry.title === "source1" && entry.boolean === true + ); + expect(allEntriesMatchAllConditions).toBe(true); + } else { + console.warn("No entries returned to verify AND condition"); } - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -// includeReference -test('.includeReference() - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && entry['reference'] && typeof entry['reference'] === 'object'); - }); - assert.equal(flag, true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeReference() - String"); - assert.end(); - }); -}); + }); -test('.includeReference() - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + test('should include entries with title set to "source1"', async () => { + if (entries && entries.length && entries[0].length) { + const allEntriesHaveCorrectTitle = entries[0].every( + (entry) => entry.title === "source1" + ); + expect(allEntriesHaveCorrectTitle).toBe(true); + } else { + console.warn("No entries returned to verify title condition"); + } + }); - Query - .includeReference(['reference', 'other_reference']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && entry['reference'] && typeof entry['reference'] === 'object' && entry['other_reference'] && typeof entry['other_reference'] === 'object'); - }); - assert.equal(flag, true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeReference() - Array"); - assert.end(); - }); -}); + test("should include entries with boolean field set to true", async () => { + if (entries && entries.length && entries[0].length) { + const allEntriesHaveBooleanTrue = entries[0].every( + (entry) => entry.boolean === true + ); + expect(allEntriesHaveBooleanTrue).toBe(true); + } else { + console.warn("No entries returned to verify boolean condition"); + } + }); + }); + + describe(".query() - Raw query", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.query({ + $or: [{ title: "source1" }, { boolean: true }], + }) + .toJSON() + .find(); + }); + + test("should return a non-empty array of entries", async () => { + expect(entries).toBeDefined(); + expect(Array.isArray(entries)).toBe(true); + expect(entries[0]).toBeDefined(); + expect(entries[0].length).toBeTruthy(); + }); + + test("should return entries matching at least one of the conditions in the raw query", async () => { + if (entries && entries.length && entries[0].length) { + const allEntriesMatchAnyCondition = entries[0].every( + (entry) => entry.title === "source1" || entry.boolean === true + ); + expect(allEntriesMatchAnyCondition).toBe(true); + } else { + console.warn("No entries returned to verify raw query conditions"); + } + }); -// includeCount -test('.includeCount()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + test('should include entries with title "source1"', async () => { + if (entries && entries.length && entries[0].length) { + const hasEntryWithTitle = entries[0].some( + (entry) => entry.title === "source1" + ); + expect(hasEntryWithTitle).toBe(true); + } else { + console.warn( + "No entries returned to verify first raw query condition" + ); + } + }); - Query - .includeCount() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeCount()"); - assert.end(); - }); -}); + test("should include entries with boolean field set to true", async () => { + if (entries && entries.length && entries[0].length) { + const hasEntryWithBoolean = entries[0].some( + (entry) => entry.boolean === true + ); + expect(hasEntryWithBoolean).toBe(true); + } else { + console.warn( + "No entries returned to verify second raw query condition" + ); + } + }); + }); + }); -// includeSchema -test('.includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + describe("custom query", () => { + test(".query() - Raw query with basic OR condition", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); - Query - .includeSchema() + const entries = await Query.query({ + $or: [{ title: "source1" }, { boolean: "true" }], + }) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1].length, 'Schema present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeSchema()"); - assert.end(); - }); -}); + .find(); + expect(entries[0].length).toBeTruthy(); -// includeCount && includeSchema -test('.includeCount() and .includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .includeSchema() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1].length, 'Schema present in the resultset'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeSchema()"); - assert.end(); + if (entries && entries.length && entries[0].length) { + const _entries = entries[0].every(function (entry) { + return entry.title === "source1" || entry.boolean === true; }); -}); + expect(_entries).toBeTruthy(); + } + }); -// includeContentType -test('.includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + test(".query() - Raw query with AND condition", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); - Query - .includeContentType() + const entries = await Query.query({ + $and: [{ title: "source1" }, { boolean: true }], + }) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeContentType()"); - assert.end(); - }); -}); + .find(); -// includeCount && includeContentType -test('.includeCount() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + expect(entries[0].length).toBeTruthy(); - Query - .includeCount() - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); - }); -}); + const allMatchBothConditions = entries[0].every( + (entry) => entry.title === "source1" && entry.boolean === true + ); + expect(allMatchBothConditions).toBeTruthy(); + }); -// includeSchema && includeContentType -test('.includeSchema() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + test(".query() - Raw query with nested conditions", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); - Query - .includeSchema() - .includeContentType() + const entries = await Query.query({ + $and: [ + { title: "source1" }, + { $or: [{ boolean: true }, { url: { $exists: true } }] }, + ], + }) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); - }); -}); + .find(); -// includeCount, includeSchema && includeContentType -test('.includeSchema() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .includeSchema() - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); - }); -}); + expect(entries[0].length).toBeTruthy(); + const allMatchConditions = entries[0].every( + (entry) => + entry.title === "source1" && + (entry.boolean === true || entry.url !== undefined) + ); + expect(allMatchConditions).toBeTruthy(); + }); + }); -// only -test('.only() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + describe("tags", () => { + test(".tags() - Multiple tags filter", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "tags"; + const tags = ["tag1", "tag2"]; - Query - .only('title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Single String Parameter"); - assert.end(); - }); -}); + const entries = await Query.tags(tags).toJSON().find(); -test('.only() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + expect(entries.length).toBeGreaterThanOrEqual(1); - Query - .only('BASE', 'title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Multiple String Parameter"); - assert.end(); + if (entries && entries.length && entries[0].length) { + const _entries = entries[0].every(function (entry) { + return Utils.arrayPresentInArray(tags, entry[field]); }); -}); - -test('.only() - Array Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only(['title', 'url']) + expect(_entries).toBe(true); + } + }); + + test(".tags() - Single tag filter", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "tags"; + const tags = ["tag1"]; + + const entries = await Query.tags(tags).toJSON().find(); + + expect(entries.length).toBeGreaterThanOrEqual(1); + + if (entries && entries.length && entries[0].length) { + const entriesWithTag = entries[0].every( + (entry) => entry[field] && entry[field].includes(tags[0]) + ); + expect(entriesWithTag).toBe(true); + } + }); + + test(".tags() - Empty results with non-existent tag", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const nonExistentTag = ["non_existent_tag_123456"]; + + const entries = await Query.tags(nonExistentTag).toJSON().find(); + + // Should return an array but with empty results + expect(entries).toBeDefined(); + expect(Array.isArray(entries)).toBe(true); + expect(entries[0].length).toBe(0); + }); + }); + + describe("search", () => { + test(".search() - Exact match", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + + const entries = await Query.search("source1").toJSON().find(); + + expect(entries[0].length).toBeTruthy(); + + const hasMatchingEntries = entries[0].some( + (entry) => + entry.title === "source1" || JSON.stringify(entry).includes("source1") + ); + expect(hasMatchingEntries).toBe(true); + }); + + test(".search() - Partial match", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + + const entries = await Query.search("source").toJSON().find(); + + expect(entries[0].length).toBeTruthy(); + + const hasMatchingEntries = entries[0].some( + (entry) => + (entry.title && entry.title.includes("source")) || + JSON.stringify(entry).includes("source") + ); + expect(hasMatchingEntries).toBe(true); + }); + + test(".search() - Case insensitive match", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + + const entries = await Query.search("SOURCE1").toJSON().find(); + + expect(entries[0].length).toBeTruthy(); + + const hasMatchingEntries = entries[0].some( + (entry) => + (entry.title && entry.title.toLowerCase() === "source1") || + JSON.stringify(entry).toLowerCase().includes("source1") + ); + expect(hasMatchingEntries).toBe(true); + }); + }); + + describe("regex", () => { + test(".regex() - Basic pattern match", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "title"; + const regex = { + pattern: "^source", + options: "i", + }; + const regexpObj = new RegExp(regex.pattern, regex.options); + + const entries = await Query.regex(field, regex.pattern, regex.options) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 3 && "title" in entry && "url" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title,url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - Array Parameter"); - assert.end(); - }); -}); - -test('.only() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', 'title') + .find(); + + expect(entries.length).toBeGreaterThanOrEqual(1); + + const flag = entries[0].every(function (entry) { + return regexpObj.test(entry[field]); + }); + expect(flag).toBeTruthy(); + }); + + test(".regex() - Specific suffix pattern", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "title"; + const regex = { + pattern: "1$", // Matches strings ending with 1 + options: "", + }; + const regexpObj = new RegExp(regex.pattern, regex.options); + + const entries = await Query.regex(field, regex.pattern, regex.options) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - For the reference - String"); - assert.end(); - }); -}); - -test('.only() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', ['title']) + .find(); + + expect(entries.length).toBeGreaterThanOrEqual(1); + + if (entries && entries[0].length) { + const matchesPattern = entries[0].every((entry) => + regexpObj.test(entry[field]) + ); + expect(matchesPattern).toBeTruthy(); + + const endsWithOne = entries[0].every( + (entry) => entry[field] && entry[field].endsWith("1") + ); + expect(endsWithOne).toBeTruthy(); + } + }); + + test(".regex() - With wildcard pattern", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const field = "title"; + const regex = { + pattern: "source.*", + options: "i", + }; + const regexpObj = new RegExp(regex.pattern, regex.options); + + const entries = await Query.regex(field, regex.pattern, regex.options) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".only() - For the reference - Array"); - assert.end(); - }); -}); - -// except -test('.except() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('title') + .find(); + + expect(entries.length).toBeGreaterThanOrEqual(1); + + if (entries && entries[0].length) { + const matchesPattern = entries[0].every((entry) => + regexpObj.test(entry[field]) + ); + expect(matchesPattern).toBeTruthy(); + } + }); + }); + + describe("locale and fallback", () => { + test("find: with specific locale", async () => { + const locale = "ja-jp"; + + const entries = await Stack.ContentType(contentTypes.source) + .Query() + .language(locale) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry)); - }); - assert.ok(flag, 'entries without the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".except() - Single String Parameter"); - assert.end(); - }); -}); - -test('.except() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('BASE', 'title') + .find(); + + expect(entries[0].length).toBeTruthy(); + + if (entries && entries.length && entries[0].length) { + const allEntriesInRequestedLocale = entries[0].every( + (entry) => + entry.publish_details && entry.publish_details.locale === locale + ); + expect(allEntriesInRequestedLocale).toBe(true); + } + }); + + test("find: with fallback enabled for partially localized content", async () => { + const primaryLocale = "ja-jp"; + const fallbackLocale = "en-us"; + + const entries = await Stack.ContentType(contentTypes.source) + .Query() + .language(primaryLocale) + .includeFallback() .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry)); - }); - assert.ok(flag, 'entries without the field title, url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".except() - Multiple String Parameter"); - assert.end(); - }); -}); + .find(); -test('.except() - Array of String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + expect(entries[0].length).toBeTruthy(); - Query - .except(['title', 'file']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry) && !("file" in entry)); - }); - assert.ok(flag, 'entries without the field title, file in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".except() - Array of String Parameter"); - assert.end(); + if (entries && entries.length && entries[0].length) { + const _entries = entries[0].every(function (entry) { + return [primaryLocale, fallbackLocale].includes( + entry.publish_details.locale + ); }); -}); - -test('.except() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', 'title') + expect(_entries).toBe(true); + } + + if (entries && entries.length && entries[0].length > 1) { + const hasPrimaryLocaleEntries = entries[0].some( + (entry) => entry.publish_details.locale === primaryLocale + ); + + const hasFallbackLocaleEntries = entries[0].some( + (entry) => entry.publish_details.locale === fallbackLocale + ); + + expect(hasPrimaryLocaleEntries || hasFallbackLocaleEntries).toBe(true); + } + }); + + test("find: comparing results with and without fallback", async () => { + const locale = "ja-jp"; + + const entriesWithoutFallback = await Stack.ContentType( + contentTypes.source + ) + .Query() + .language(locale) .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - var _flag; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - _flag = true; - _flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); - } else { - _flag = false; - } - return (_flag && entry && Object.keys(entry).length === 2 && "reference" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries withthe field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".except() - For the reference - String"); - assert.end(); - }); -}); - -test('.except() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + .find(); - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', ['title']) + const entriesWithFallback = await Stack.ContentType(contentTypes.source) + .Query() + .language(locale) + .includeFallback() .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - var _flag; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - _flag = true; - _flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); - } else { - _flag = false; - } - return (_flag && entry && Object.keys(entry).length === 2 && "reference" in entry && "uid" in entry); + .find(); + + expect(entriesWithFallback[0].length).toBeGreaterThanOrEqual( + entriesWithoutFallback[0].length + ); + + if (entriesWithoutFallback && entriesWithoutFallback[0].length) { + const allInRequestedLocale = entriesWithoutFallback[0].every( + (entry) => entry.publish_details.locale === locale + ); + expect(allInRequestedLocale).toBe(true); + } + }); + }); + + describe("include reference", () => { + describe(".includeReference() - String", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference").toJSON().find(); + }); + + test("should return entries with the reference field", () => { + expect(entries[0].length).toBeGreaterThan(0); + }); + + test("should include the reference field as an object", () => { + const allEntriesHaveReference = entries[0].every( + (entry) => + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ); + expect(allEntriesHaveReference).toBe(true); + }); + }); + + describe(".includeReference() - Array", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference(["reference", "other_reference"]) + .toJSON() + .find(); + }); + + test("should return entries with data", () => { + expect(entries[0].length).toBeGreaterThan(0); + }); + + test("should include the first reference field as an object", () => { + const allEntriesHaveFirstReference = entries[0].every( + (entry) => + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ); + expect(allEntriesHaveFirstReference).toBe(true); + }); + + test("should include the second reference field as an object", () => { + const allEntriesHaveSecondReference = entries[0].every( + (entry) => + entry && + entry["other_reference"] && + typeof entry["other_reference"] === "object" + ); + expect(allEntriesHaveSecondReference).toBe(true); + }); + }); + }); + + describe("include count and schema", () => { + describe(".includeCount()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount().toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include count information", () => { + expect(entries[1]).toBeTruthy(); + }); + }); + + describe(".includeSchema()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeSchema().toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include schema information", () => { + expect(entries[1].length).toBeTruthy(); + }); + }); + + describe(".includeCount() and .includeSchema()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount().includeSchema().toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include schema information", () => { + expect(entries[1].length).toBeTruthy(); + }); + + test("should include count information", () => { + expect(entries[2]).toBeTruthy(); + }); + }); + }); + + describe("include contenttypes", () => { + describe(".includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeContentType().toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include content type information", () => { + expect(entries[1]).toBeTruthy(); + }); + + test("should include content type title", () => { + expect(entries[1]["title"]).toBeTruthy(); + }); + + test("should have the correct content type UID", () => { + expect(entries[1]["uid"]).toBe(contentTypes.source); + }); + }); + + describe(".includeCount() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount() + .includeContentType() + .toJSON() + .find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include content type information", () => { + expect(entries[1]).toBeTruthy(); + }); + + test("should include content type title", () => { + expect(entries[1]["title"]).toBeTruthy(); + }); + + test("should have the correct content type UID", () => { + expect(entries[1]["uid"]).toBe(contentTypes.source); + }); + + test("should include count information", () => { + expect(entries[2]).toBeTruthy(); + }); + }); + + describe(".includeSchema() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeSchema() + .includeContentType() + .toJSON() + .find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include content type information", () => { + expect(entries[1]).toBeTruthy(); + }); + + test("should include content type title", () => { + expect(entries[1]["title"]).toBeTruthy(); + }); + + test("should have the correct content type UID", () => { + expect(entries[1]["uid"]).toBe(contentTypes.source); + }); + }); + + describe(".includeCount(), .includeSchema() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include content type information", () => { + expect(entries[1]).toBeTruthy(); + }); + + test("should include content type title", () => { + expect(entries[1]["title"]).toBeTruthy(); + }); + + test("should have the correct content type UID", () => { + expect(entries[1]["uid"]).toBe(contentTypes.source); + }); + + test("should include count information", () => { + expect(entries[2]).toBeTruthy(); + }); + }); + }); + + describe("field projections", () => { + describe(".only() - Single String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only("title").toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include only the title and uid fields", () => { + const correctFieldsOnly = entries[0].every( + (entry) => + entry && + Object.keys(entry).length === 2 && + "title" in entry && + "uid" in entry + ); + expect(correctFieldsOnly).toBeTruthy(); + }); + }); + + describe(".only() - Multiple String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only("BASE", "title").toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include only the title and uid fields", () => { + const correctFieldsOnly = entries[0].every( + (entry) => + entry && + Object.keys(entry).length === 2 && + "title" in entry && + "uid" in entry + ); + expect(correctFieldsOnly).toBeTruthy(); + }); + }); + + describe(".only() - Array Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only(["title", "url"]).toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should include only the title, url, and uid fields", () => { + const correctFieldsOnly = entries[0].every( + (entry) => + entry && + Object.keys(entry).length === 3 && + "title" in entry && + "url" in entry && + "uid" in entry + ); + expect(correctFieldsOnly).toBeTruthy(); + }); + }); + + describe(".except() - Single String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except("title").toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should exclude the title field", () => { + const titleExcluded = entries[0].every( + (entry) => entry && !("title" in entry) + ); + expect(titleExcluded).toBeTruthy(); + }); + }); + + describe(".except() - Multiple String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except("BASE", "title").toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should exclude the title field", () => { + const titleExcluded = entries[0].every( + (entry) => entry && !("title" in entry) + ); + expect(titleExcluded).toBeTruthy(); + }); + }); + + describe(".except() - Array of String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except(["title", "file"]).toJSON().find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should exclude the title field", () => { + const titleExcluded = entries[0].every( + (entry) => entry && !("title" in entry) + ); + expect(titleExcluded).toBeTruthy(); + }); + + test("should exclude the file field", () => { + const fileExcluded = entries[0].every( + (entry) => entry && !("file" in entry) + ); + expect(fileExcluded).toBeTruthy(); + }); + }); + + describe(".except() - For the reference - String", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .except("reference", "title") + .toJSON() + .find(); + }); + + test("should return entries", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("should properly format entries with reference but without title in references", () => { + const correctFormat = entries[0].every((entry) => { + let hasCorrectReferenceFormat = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + hasCorrectReferenceFormat = true; + hasCorrectReferenceFormat = entry.reference.every((reference) => { + return reference && !("title" in reference); }); - assert.ok(flag, 'entries with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".except() - For the reference - Array"); - assert.end(); + } + + return ( + hasCorrectReferenceFormat && + entry && + Object.keys(entry).length === 2 && + "reference" in entry && + "uid" in entry + ); }); -}); \ No newline at end of file + + expect(correctFormat).toBeTruthy(); + }); + }); + }); +}); diff --git a/test/entry/find.js b/test/entry/find.js index 7c4c2c57..07276a30 100755 --- a/test/entry/find.js +++ b/test/entry/find.js @@ -1,1676 +1,1414 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const test = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const init = require('../config.js'); -const Utils = require('./utils.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); +const Utils = require("./utils.js"); const contentTypes = init.contentTypes; let Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); -test('early_access in stack initialization', function (t) { - const stack = Contentstack.Stack({ ...init.stack, early_access: ['newCDA', 'taxonomy'] }); - t.equal(stack.headers['x-header-ea'], 'newCDA,taxonomy', 'Early access headers should be added'); - t.end(); -}); +describe("ContentStack SDK Tests", () => { + // Setup - Initialize the Contentstack Stack Instance + beforeAll((done) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(done, 1000); + }); + + describe("Stack Initialization", () => { + test("early_access in stack initialization should add headers", () => { + const stack = Contentstack.Stack({ + ...init.stack, + early_access: ["newCDA", "taxonomy"], + }); + expect(stack.headers["x-header-ea"]).toBe("newCDA,taxonomy"); + }); + }); + + describe("Default Find", () => { + let entries; + const field = "updated_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Count should not be present", () => { + expect(entries[1]).toBeFalsy(); + }); + + test("Entries should be sorted by default in descending order of updated_at", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe("Sorting", () => { + describe(".ascending()", () => { + let entries; + const field = "updated_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.ascending(field).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Entries should be sorted in ascending order", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] >= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".descending()", () => { + let entries; + const field = "created_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.descending(field).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Entries should be sorted in descending order", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + }); + + describe("Parameters", () => { + describe(".addParam()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.addParam("include_count", "true").toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Count should be present", () => { + expect(entries[1]).toBeTruthy(); + }); + }); + }); + + describe("Comparison", () => { + describe(".lessThan()", () => { + let entries; + const field = "num_field"; + const value = 11; + + test("Should return entry in the resultset", async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + + const result = await Query.lessThan("num_field", value).toJSON().find(); + + entries = result; + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have num_field less than specified value", () => { + if (entries && entries.length && entries[0].length) { + const allLessThan = entries[0].every((entry) => entry[field] < value); + expect(allLessThan).toBe(true); + } + }); + }); + + describe(".lessThanOrEqualTo()", () => { + let entries; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entries = await Query.lessThanOrEqualTo("num_field", value) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have num_field less than or equal to specified value", () => { + const allLessThanOrEqual = entries[0].every( + (entry) => entry[field] <= value + ); + expect(allLessThanOrEqual).toBe(true); + }); + + test("Entries should be sorted in descending order by default", () => { + const updatedAtField = "updated_at"; + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][updatedAtField]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[updatedAtField] <= prev; + prev = entry[updatedAtField]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".greaterThan()", () => { + let entries; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entries = await Query.greaterThan("num_field", value) + .ascending(field) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have num_field greater than specified value", () => { + const allGreaterThan = entries[0].every( + (entry) => entry[field] > value + ); + expect(allGreaterThan).toBe(true); + }); + + test("Entries should be sorted in ascending order", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] >= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".greaterThanOrEqualTo()", () => { + let entries; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entries = await Query.greaterThanOrEqualTo("num_field", value) + .descending(field) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have num_field greater than or equal to specified value", () => { + const allGreaterThanOrEqual = entries[0].every( + (entry) => entry[field] >= value + ); + expect(allGreaterThanOrEqual).toBe(true); + }); + + test("Entries should be sorted in descending order", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".notEqualTo()", () => { + let entries; + const field = "num_field"; + const value = 6; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entries = await Query.notEqualTo("num_field", value) + .descending(field) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have num_field not equal to specified value", () => { + const allNotEqual = entries[0].every((entry) => entry[field] !== value); + expect(allNotEqual).toBe(true); + }); + + test("Entries should be sorted in descending order", () => { + if (entries && entries.length && entries[0].length > 1) { + let prev = entries[0][0][field]; + const sortedCorrectly = entries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".where() with boolean value (true)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.where("boolean", true).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return four entries in the resultset", () => { + expect(entries[0].length).toBe(4); + }); + + test("All entries should have boolean field set to true", () => { + const allTrue = entries[0].every((entry) => entry.boolean === true); + expect(allTrue).toBe(true); + }); + }); + + describe(".where() with boolean value (false)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.where("boolean", false).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return three entries in the resultset", () => { + expect(entries[0].length).toBe(3); + }); + + test("All entries should have boolean field set to false", () => { + const allFalse = entries[0].every((entry) => entry.boolean === false); + expect(allFalse).toBe(true); + }); + }); + + describe(".where() with empty string", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.where("title", "").toJSON().find(); + }); + + test("Should return zero entries in the resultset", () => { + expect(entries[0].length).toBe(0); + }); + }); + describe(".tags()", () => { + let entries; + const field = "tags"; + const tags = ["tag1", "tag2"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.tags(tags).toJSON().find(); + }); + + test("Should return one or more entries in the resultset", () => { + expect(entries.length).toBeGreaterThanOrEqual(1); + }); + + test("All entries should have at least one of the specified tags", () => { + if (entries && entries.length && entries[0].length) { + const allHaveTags = entries[0].every((entry) => + Utils.arrayPresentInArray(tags, entry[field]) + ); + expect(allHaveTags).toBe(true); + } else { + // Skip this test if no entries were found + console.log("No entries found to check tags"); + } + }); + }); + }); + + describe("Array/Subset Tests", () => { + describe(".containedIn()", () => { + let entries; + const _in = ["source1", "source2"]; + const field = "title"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.containedIn("title", _in).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return two entries in the resultset", () => { + expect(entries[0].length).toBe(2); + }); + + test("All entries should have title field contained in the specified values", () => { + if (entries && entries.length && entries[0].length) { + const allContained = entries[0].every((entry) => + _in.includes(entry[field]) + ); + expect(allContained).toBe(true); + } + }); + }); -test('default .find()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.notok(entries[1], 'Count should not be present'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("default .find()"); - assert.end(); + describe(".notContainedIn()", () => { + let entries; + const _in = ["source1", "source2"]; + const field = "title"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.notContainedIn("title", _in).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return three entries in the resultset", () => { + expect(entries[0].length).toBe(5); + }); + + test("All entries should have title field not contained in the specified values", () => { + if (entries && entries.length && entries[0].length) { + const allNotContained = entries[0].every( + (entry) => !_in.includes(entry[field]) + ); + expect(allNotContained).toBe(true); + } + }); + }); + test(".exists() should return entries with the specified field", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const queryField = "boolean"; + const field = "updated_at"; + const entries = await Query.exists(queryField).toJSON().find(); + + // Check if entries are returned + expect(entries[0].length).toBeTruthy(); + + // Verify sorting order (descending on updated_at) + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + const flag = entry[field] <= prev; + prev = entry[field]; + return flag; }); -}); + expect(_entries).toBe(true); + } + }); + + test(".notExists() should return entries without the specified field", async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + const queryField = "isspecial"; + const field = "updated_at"; + const entries = await Query.notExists(queryField).toJSON().find(); + + // Check if entries are returned + expect("entries" in entries).toBeTruthy(); + + // Verify sorting order if entries exist + if (entries && entries.length && entries[0].length) { + let prev = entries[0][0][field]; + const _entries = entries[0].every(function (entry) { + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } + }); + }); + + describe("Pagination Tests", () => { + describe(".skip()", () => { + let allEntries; + let skippedEntries; + const field = "updated_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + allEntries = await Query.toJSON().find(); + + const SkipQuery = Stack.ContentType(contentTypes.source).Query(); + skippedEntries = await SkipQuery.skip(1).toJSON().find(); + }); + + test("All entries should be present in the resultset", () => { + expect(allEntries[0].length).toBeTruthy(); + }); + + test("Skipped entries should be present in the resultset", () => { + expect(skippedEntries[0].length).toBeGreaterThanOrEqual(2); + }); + + test("Skipped entries should match all entries with first skipped", () => { + expect(skippedEntries[0]).toEqual(allEntries[0].slice(1)); + }); + + test("Skipped entries should maintain sorting order", () => { + if ( + skippedEntries && + skippedEntries.length && + skippedEntries[0].length > 1 + ) { + let prev = skippedEntries[0][0][field]; + const sortedCorrectly = skippedEntries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".limit()", () => { + let allEntries; + let limitedEntries; + const field = "updated_at"; + const limitNumber = 2; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + allEntries = await Query.toJSON().find(); + + const LimitQuery = Stack.ContentType(contentTypes.source).Query(); + limitedEntries = await LimitQuery.limit(limitNumber).toJSON().find(); + }); + + test("All entries should be present in the resultset", () => { + expect(allEntries[0].length).toBeTruthy(); + }); + + test("Limited entries should be present in the resultset", () => { + expect(limitedEntries[0].length).toBeTruthy(); + }); + + test("Limited entries should match first N entries from all entries", () => { + expect(limitedEntries[0]).toEqual(allEntries[0].slice(0, limitNumber)); + }); + + test("Limited entries should maintain sorting order", () => { + if ( + limitedEntries && + limitedEntries.length && + limitedEntries[0].length > 1 + ) { + let prev = limitedEntries[0][0][field]; + const sortedCorrectly = limitedEntries[0].slice(1).every((entry) => { + const isValid = entry[field] <= prev; + prev = entry[field]; + return isValid; + }); + expect(sortedCorrectly).toBe(true); + } + }); + }); + + describe(".count()", () => { + let count; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + count = await Query.count().toJSON().find(); + }); + + test("Entries present in the resultset", () => { + expect(count).toBeTruthy(); + }); + }); + }); + + describe("Logical Operations", () => { + describe(".or() - Query Objects", () => { + let entries; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .where("title", "source2"); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entries = await Query.or(Query1, Query2).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return 1 entries in the resultset", () => { + expect(entries[0].length).toBe(5); + }); + + test("All entries should satisfy the OR condition", () => { + if (entries && entries.length && entries[0].length) { + let _entries = entries[0].every(function (entry) { + return ~(entry.title === "source1" || entry.boolean === true); + }); + expect(_entries).toBe(true); + } + }); + }); -/*! - * SORTING - * !*/ -test('.ascending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .ascending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - prev = entry[field]; - return (entry[field] >= prev); - }); - assert.equal(_entries, true, "entries sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".ascending()"); - assert.end(); + describe(".and() - Query Objects", () => { + let entries; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .where("title", "source1"); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entries = await Query.and(Query1, Query2).toJSON().find(); + }); + + test("Should return one entry in the resultset", () => { + expect(entries[0].length).toBe(1); + }); + + test("All entries should satisfy the AND condition", () => { + if (entries && entries.length && entries[0].length) { + const allMatchCondition = entries[0].every( + (entry) => entry.title === "source1" && entry.boolean === true + ); + expect(allMatchCondition).toBe(true); + } + }); + }); + + describe(".query() - Raw query", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.query({ + $or: [{ title: "source2" }, { boolean: "true" }], + }) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("Should return two entries in the resultset", () => { + expect(entries[0].length).toBe(1); + }); + + test("All entries should satisfy the OR condition", () => { + if (entries && entries.length && entries[0].length) { + const allMatchCondition = entries[0].every( + (entry) => entry.title === "source2" || entry.boolean === false + ); + expect(allMatchCondition).toBe(true); + } + }); + }); + + describe("Search Tests", () => { + describe(".search()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.toJSON().search("source2").find(); }); -}); -test('.descending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'created_at'; - - Query - .descending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".descending()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + }); + + describe("Including Additional Data Tests", () => { + describe(".includeCount() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount() + .includeContentType() + .toJSON() + .find(); }); -}); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); -// addparam -test('.addParam()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); + test("ContentType should be present in the resultset", () => { + expect(entries[1]).toBeTruthy(); + }); - Query - .addParam('include_count', 'true') - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries length present in the resultset'); - assert.ok(entries[1], 'count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".addParam()"); - assert.end(); + test("ContentType title should exist", () => { + expect(entries[1].title).toBeDefined(); }); -}); + test("ContentType uid should match requested content type", () => { + expect(entries[1].uid).toBe(contentTypes.source); + }); -/*! - * COMPARISION - * !*/ -test('.lessThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - Query - .lessThan('num_field', value) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].slice(1).every(function(entry) { - var flag = (entry[field] < value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error('Error : ', err); - assert.fail(".lessThan()"); - assert.end(); + test("Count should be present in the resultset", () => { + expect(entries[2]).toBeTruthy(); }); -}); + }); -test('.lessThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'updated_at', - value = 11; - - Query - .lessThanOrEqualTo('num_field', value) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".lessThanOrEqualTo()"); - assert.end(); + describe(".includeEmbeddedItems()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeEmbeddedItems().toJSON().find(); }); -}); -test('.greaterThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - - Query - .greaterThan('num_field', value) - .ascending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].slice(1).every(function(entry) { - var flag = (entry[field] > value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted ascending on '" + field + "' field"); - } - assert.end(); - }, function error() { - assert.fail(".greaterThan()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); -test('.greaterThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - - Query - .greaterThanOrEqualTo('num_field', value) - .descending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] >= value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".greaterThanOrEqualTo()"); - assert.end(); + describe(".includeSchema() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeSchema() + .includeContentType() + .toJSON() + .find(); }); -}); -test('.notEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 6; - - Query - .notEqualTo('num_field', value) - .descending(field) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] != value); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notEqualTo()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -test('.where() compare boolean value (true)', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .where('boolean', true) - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.equal(entries[0].length, 4, 'two entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where()"); - assert.end(); + test("ContentType should be present in the resultset", () => { + expect(entries[1]).toBeTruthy(); }); -}); -test('.where() compare boolean value (false)', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .where('boolean', false) - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.equal(entries[0].length, 3, ' three entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where() boolean value having false"); - assert.end(); + test("ContentType title should exist", () => { + expect(entries[1].title).toBeDefined(); }); -}); -test('.where()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .where('title', '') - .toJSON() - .find() - .then(function success(entries) { - assert.equal(entries[0].length, 0, ' zero entry present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".equalTo compare boolean value (true)"); - assert.end(); + test("ContentType uid should match requested content type", () => { + expect(entries[1].uid).toBe(contentTypes.source); + }); + }); + + describe(".includeCount(), .includeSchema() and .includeContentType()", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find(); }); -}); -test('.equalTo() compare boolean value (true)', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .equalTo('boolean', true) - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.equal(entries[0].length, 4, ' four entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -test('.equalTo() compare boolean value (false)', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .equalTo('boolean', false) - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.equal(entries[0].length, 3, ' three entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".where() boolean value having false"); - assert.end(); + test("ContentType should be present in the resultset", () => { + expect(entries[1]).toBeTruthy(); }); -}); -// /*! -// * Array/Subset -// * !*/ - -test('.containedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2"], - field = 'updated_at'; - - Query - .containedIn('title', _in) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[0].length, 2, 'two entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['title']) != -1); - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".containedIn()"); - assert.end(); + test("ContentType title should exist", () => { + expect(entries[1].title).toBeDefined(); }); -}); -test('.notContainedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2"]; - - Query - .notContainedIn('title', _in) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(entries[0].length, 'No Entry present in the resultset'); - assert.ok(entries[0].length, 3, 'three Entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notContainedIn()"); - assert.end(); + test("ContentType uid should match requested content type", () => { + expect(entries[1].uid).toBe(contentTypes.source); }); -}); + test("Count should be present in the resultset", () => { + expect(entries[2]).toBeTruthy(); + }); + }); + }); + + describe("Localization Tests", () => { + describe("find: without fallback", () => { + let entries; + const _in = ["ja-jp"]; + + beforeAll(async () => { + entries = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .toJSON() + .find(); + }); -/*! - *Element(exists) - * !*/ - -test('.exists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "boolean", - field = 'updated_at'; - - Query - .exists(queryField) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".exists()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -test('.notExists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "isspecial", - field = 'updated_at'; - - Query - .notExists(queryField) - .toJSON() - .find() - .then(function success(entries) { - assert.ok("entries" in entries, 'Entries key present in the resultset'); - //assert.notok(entries[0].length, 'No entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); + test("All entries should have the correct locale", () => { + if (entries && entries[0].length) { + const allHaveCorrectLocale = entries[0].every((entry) => + _in.includes(entry.publish_details.locale) + ); + expect(allHaveCorrectLocale).toBe(true); + } + }); + }); + + describe("find: with fallback", () => { + let entries; + const _in = ["ja-jp", "en-us"]; + + beforeAll(async () => { + entries = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .includeFallback() + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have locale from the allowed fallback list", () => { + if (entries && entries[0].length) { + const allHaveCorrectLocale = entries[0].every((entry) => + _in.includes(entry.publish_details.locale) + ); + expect(allHaveCorrectLocale).toBe(true); + } + }); + }); + }); + + describe("Global Field Tests", () => { + describe(".getContentTypes()", () => { + let entries; + + beforeAll(async () => { + entries = await Stack.getContentTypes({ + include_global_field_schema: true, + }); + }); + + test("Global field schema should be present when applicable", () => { + for (var i = 0; i < entries.content_types[0].schema.length; i++) { + if ( + entries.content_types[0].schema[i].data_type === "global_field" + ) { + expect(entries[1]["schema"][i]["schema"]).toBeDefined(); } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".notExists()"); - assert.end(); + } }); -}); + }); + }); + describe("Field Selection Tests", () => { + describe(".only() - Single String Parameter", () => { + let entries; -// Pagination -test('.skip()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .toJSON() - .find() - .then(function success(allEntries) { - //assert.equal(Utils.isEntriesPublished(allEntries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - // assert.ok("entries" in allEntries, 'Entries key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .skip(1) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok((entries[0].length >= 2), '2 or more Entries present in the resultset'); - assert.deepEqual(allEntries[0].slice(1), entries[0], 'All elements matched.'); - if (entries && entries.length && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".skip()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".skip()"); - assert.end(); + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only("title").toJSON().find(); }); -}); -test('.limit()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .toJSON() - .find() - .then(function success(allEntries) { - //assert.equal(Utils.isEntriesPublished(allEntries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - // assert.ok("entries" in allEntries, 'Entries key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .limit(2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.deepEqual(allEntries[0].slice(0, 2), entries[0], 'All elements matched.'); - if (entries && entries.length && entries[0] && entries[0].length) { - var prev = entries[0][0][field]; - var _entries = entries[0].every(function(entry) { - var flag = (entry[field] <= prev); - prev = entry[field]; - return flag; - }); - assert.equal(_entries, true, "entries sorted descending on '" + field + "' field"); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); - }); - }, function error(err) { - console.error("error :", err); - assert.fail(".limit()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -test('.count()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .count() - .toJSON() - .find() - .then(function success(count) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.ok(count, 'Entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".count()"); - assert.end(); + test("All entries should contain only title and uid fields", () => { + const allHaveCorrectFields = entries[0].every( + (entry) => + Object.keys(entry).length === 2 && + "title" in entry && + "uid" in entry + ); + expect(allHaveCorrectFields).toBe(true); }); -}); + }); + describe(".only() - Multiple String Parameter", () => { + let entries; -// Logical -test('.or() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().where('title', 'source2'); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .or(Query1, Query2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[0].length, 2, 'two entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (~(entry.title === 'source1' || entry.boolean === true)); - }); - assert.ok(_entries, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".or() - Query Objects"); - assert.end(); + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only("BASE", "title").toJSON().find(); }); -}); -test('.and() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().where('title', 'source1'); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - if (entries && entries.length && entries[0].length) { - // console.log("\n\n\n\n",JSON.stringify(entries)); - var _entries = entries[0].every(function(entry) { - return (~(entry.title === 'source1' || entry.boolean === true)); - }); - assert.ok(_entries, '$AND condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".and() - Query Objects"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -// Custom query -test('.query() - Raw query', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .query({ "$or": [{ "title": "source2" }, { "boolean": "true" }] }) - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[0].length, 2, 'two entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (entry.title === 'source2' || entry.boolean === false) - }); - assert.ok(_entries, '$OR condition satisfied'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".query() - Raw query"); - assert.end(); + test("All entries should contain only title and uid fields", () => { + const allHaveCorrectFields = entries[0].every( + (entry) => + Object.keys(entry).length === 2 && + "title" in entry && + "uid" in entry + ); + expect(allHaveCorrectFields).toBe(true); }); -}); + }); + describe(".only() - Array Parameter", () => { + let entries; -// tags -test('.tags()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'tags', - tags = ["tag1", "tag2"]; - - Query - .tags(tags) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - // assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok((entries.length >= 1), '1 or more Entry/Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (Utils.arrayPresentInArray(tags, entry[field])); - }); - assert.equal(_entries, true, 'Tags specified are found in result set'); - } - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".tags()"); - assert.end(); + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.only(["title", "url"]).toJSON().find(); }); -}); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); -// search -test('.search()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .toJSON() - .search('source2') - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, '1 Entry present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".search()"); - assert.end(); + test("All entries should contain only title, url, and uid fields", () => { + const allHaveCorrectFields = entries[0].every( + (entry) => + Object.keys(entry).length === 3 && + "title" in entry && + "url" in entry && + "uid" in entry + ); + expect(allHaveCorrectFields).toBe(true); + }); + }); + + describe(".only() - For the reference - String", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .only("reference", "title") + .toJSON() + .find(); }); -}); -// regex -test('.regex()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'title', - regex = { - pattern: '^source', - options: 'i' - }, - regexpObj = new RegExp(regex.pattern, regex.options); - - Query - .regex(field, regex.pattern, regex.options) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok((entries.length >= 1), '1 or more Entry/Entries present in the resultset'); - var flag = entries[0].every(function(entry) { - return regexpObj.test(entry[field]); - }); - assert.ok(flag, "regexp satisfied for all the entries in the resultset"); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".regex()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -// inlcudeEmbeddedItems -test('.inlcudeEmbeddedItems()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeEmbeddedItems() - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".inlcudeEmbeddedItems()"); - assert.end(); + test("All entries should contain reference field", () => { + const allHaveReference = entries[0].every( + (entry) => "reference" in entry + ); + expect(allHaveReference).toBe(true); + }); + }); + + describe(".only() - For the reference - Array", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .only("reference", ["title"]) + .toJSON() + .find(); }); -}); -test('find: without fallback', function(assert) { - var _in = ['ja-jp'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .toJSON() - .find() - .then((entries) => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['publish_details']['locale']) != -1); - }); - assert.equal(_entries, true, "Publish content fallback"); - } - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('find: fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .includeFallback() - .toJSON() - .find() - .then((entries) => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - if (entries && entries.length && entries[0].length) { - var _entries = entries[0].every(function(entry) { - return (_in.indexOf(entry['publish_details']['locale']) != -1); - }); - assert.equal(_entries, true, "Publish content fallback"); - } - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -// includeContentType -test('.includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1]['schema'], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - for(var i=0; i { + expect(entries[0].length).toBeTruthy(); }); -}); -test('.getContentTypes()', function(assert) { - var Query = Stack.getContentTypes({"include_global_field_schema": true}) - Query - .then(function success(entries) { - for(var i=0; i { + const allHaveReference = entries[0].every( + (entry) => "reference" in entry + ); + expect(allHaveReference).toBe(true); }); -}); + }); + }); + + describe("Field Exclusion Tests", () => { + describe(".except() - Single String Parameter", () => { + let entries; -// includeReference -test('.includeReference() - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .toJSON() - .find() - .then(function success(entries) { - var flag = entries[0].every(function(entry) { - return (entry && entry.reference && typeof entry.reference === 'object'); - }); - assert.equal(flag, true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeReference() - String"); - assert.end(); + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except("title").toJSON().find(); }); -}); -test('.includeReference() - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference(['reference', 'other_reference']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - var flag = entries[0].every(function(entry) { - return (entry && entry.reference && typeof entry.reference === 'object' && entry.other_reference && typeof entry.other_reference === 'object'); - }); - assert.equal(flag, true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeReference() - Array"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); -// includeCount -test('.includeCount()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeCount()"); - assert.end(); + test("All entries should not have title field", () => { + const allExcluded = entries[0].every( + (entry) => entry && !("title" in entry) + ); + expect(allExcluded).toBe(true); }); -}); + }); -// includeSchema -test('.includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'Schema present in the resultset'); - for(var i=0; i { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except("BASE", "title").toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should not have title field", () => { + const allExcluded = entries[0].every( + (entry) => entry && !("title" in entry) + ); + expect(allExcluded).toBe(true); + }); + }); + + describe(".except() - Array of String Parameter", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.except(["title", "file"]).toJSON().find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should not have title and file fields", () => { + const allExcluded = entries[0].every( + (entry) => entry && !("title" in entry) && !("file" in entry) + ); + expect(allExcluded).toBe(true); + }); + }); + + describe(".except() - For the reference - String", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .except("reference", "title") + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have reference field", () => { + const allHaveReference = entries[0].every( + (entry) => entry && "reference" in entry + ); + expect(allHaveReference).toBe(true); + }); + + test("All entries should have uid field", () => { + const allHaveUID = entries[0].every( + (entry) => entry && "uid" in entry + ); + expect(allHaveUID).toBe(true); }); -}); -// includeReferenceContenttypeUid with an object -test('.includeReferenceContenttypeUid()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .includeReferenceContentTypeUID() - .toJSON() - .find() - .then(function success(entries) { - for(var i=0; i { + let allReferencesExcluded = true; + + entries[0].forEach((entry) => { + if ( + entry && + entry.reference && + typeof entry.reference === "object" + ) { + entry.reference.forEach((reference) => { + if (reference && "title" in reference) { + allReferencesExcluded = false; } + }); } - }, function error(err) { - console.error("error :", err); - assert.fail(".includeSchema()"); - assert.end(); + }); + + expect(allReferencesExcluded).toBe(true); + }); + }); + + describe(".except() - For the reference - Array", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entries = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .except("reference", ["title"]) + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + + test("All entries should have reference field", () => { + const allHaveReference = entries[0].every( + (entry) => entry && "reference" in entry + ); + expect(allHaveReference).toBe(true); }); -}); + test("All entries should have uid field", () => { + const allHaveUID = entries[0].every( + (entry) => entry && "uid" in entry + ); + expect(allHaveUID).toBe(true); + }); -// includeReferenceContenttypeUid with string -test('.includeReferenceContenttypeUid()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .includeReferenceContentTypeUID() - .toJSON() - .find() - .then(function success(entries) { - for(var i=0; i { + let allReferencesExcluded = true; + + entries[0].forEach((entry) => { + if ( + entry && + entry.reference && + typeof entry.reference === "object" + ) { + entry.reference.forEach((reference) => { + if (reference && "title" in reference) { + allReferencesExcluded = false; } + }); } - }, function error(err) { - console.error("error :", err); - assert.fail(".includeReferenceContenttypeUid()"); - assert.end(); + }); + + expect(allReferencesExcluded).toBe(true); + }); + }); + }); + + describe("Taxonomies Endpoint Tests", () => { + describe("Get Entries With One Term", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.Taxonomies(); + entries = await Query.where("taxonomies.one", "term_one") + .toJSON() + .find(); }); -}); -// includeCount && includeSchema -test('.includeCount() and .includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .includeSchema() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1].length, 'Schema present in the resultset'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeSchema()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + + describe("Get Entries With Any Term ($in)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.Taxonomies(); + entries = await Query.containedIn("taxonomies.one", [ + "term_one", + "term_two", + ]) + .toJSON() + .find(); }); -}); -// includeContentType -test('.includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".includeContentType()"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); -// includeCount && includeContentType -test('.includeCount() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); + describe("Get Entries With Any Term ($or)", () => { + let entries; + + beforeAll(async () => { + const Query1 = Stack.Taxonomies().where("taxonomies.one", "term_one"); + const Query2 = Stack.Taxonomies().where("taxonomies.two", "term_two"); + const Query = Stack.Taxonomies(); + + entries = await Query.or(Query1, Query2).toJSON().find(); }); -}); -// includeSchema && includeContentType -test('.includeSchema() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); -// includeCount, includeSchema && includeContentType -test('.includeSchema() and .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeCount() - .includeSchema() - .includeContentType() - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - //assert.equal(Utils.isEntriesPublished(entries[0], Stack.environment_uid, 'en-us'), true, "Entries present in the resultset are published."); - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.ok(entries[1], 'ContentType present in the resultset'); - assert.ok(entries[1]['title'], 'ContentType title exists'); - assert.ok((entries[1]['uid'] === contentTypes.source), 'ContentType uid is same as requested'); - assert.ok(entries[2], 'Count present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(".includeCount && includeContentType"); - assert.end(); + describe("Get Entries With All Terms ($and)", () => { + let entries; + + beforeAll(async () => { + const Query1 = Stack.Taxonomies().where("taxonomies.one", "term_one"); + const Query2 = Stack.Taxonomies().where("taxonomies.two", "term_two"); + const Query = Stack.Taxonomies(); + + entries = await Query.and(Query1, Query2).toJSON().find(); }); -}); -// only -test('.only() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Single String Parameter"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); + + describe("Get Entries With Any Taxonomy Terms ($exists)", () => { + let entries; -test('.only() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('BASE', 'title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Multiple String Parameter"); - assert.end(); + beforeAll(async () => { + const Query = Stack.Taxonomies(); + entries = await Query.exists("taxonomies.one").toJSON().find(); }); -}); -test('.only() - Array Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only(['title', 'url']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && Object.keys(entry).length === 3 && "title" in entry && "url" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field title,url in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - Array Parameter"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + }); + + describe("Content Type Taxonomies Query Tests", () => { + describe("Get Entries With One Term", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.where("taxonomies.one", "term_one") + .toJSON() + .find(); }); -}); -test('.only() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', 'title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - For the reference - String"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + + describe("Get Entries With Any Term ($in)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.containedIn("taxonomies.one", [ + "term_one", + "term_two", + ]) + .toJSON() + .find(); }); -}); -test('.only() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', ['title']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".only() - For the reference - Array"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); + + describe("Get Entries With Any Term ($or)", () => { + let entries; -// except -test('.except() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry)); - }); - assert.ok(flag, 'entries without the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".except() - Single String Parameter"); - assert.end(); + beforeAll(async () => { + const Query1 = Stack.ContentType("source") + .Query() + .where("taxonomies.one", "term_one"); + const Query2 = Stack.ContentType("source") + .Query() + .where("taxonomies.two", "term_two"); + const Query = Stack.ContentType("source").Query(); + + entries = await Query.or(Query1, Query2).toJSON().find(); }); -}); -test('.except() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('BASE', 'title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry)); - }); - assert.ok(flag, 'entries without the field title, url in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".except() - Multiple String Parameter"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); + + describe("Get Entries With All Terms ($and)", () => { + let entries; -test('.except() - Array of String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except(['title', 'file']) - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - return (entry && !("title" in entry) && !("file" in entry)); - }); - assert.ok(flag, 'entries without the field title, file in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".except() - Array of String Parameter"); - assert.end(); + beforeAll(async () => { + const Query1 = Stack.ContentType("source") + .Query() + .where("taxonomies.one", "term_one"); + const Query2 = Stack.ContentType("source") + .Query() + .where("taxonomies.two", "term_two"); + const Query = Stack.ContentType("source").Query(); + + entries = await Query.and(Query1, Query2).toJSON().find(); }); -}); -test('.except() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', 'title') - .toJSON() - .find() - .then(function success(entries) { - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - var _flag; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - _flag = true; - _flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); - } else { - _flag = true; - } - return (_flag && entry && (Object.keys(entry).length === 3 || Object.keys(entry).length === 2) && "reference" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".except() - For the reference - String"); - assert.end(); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); }); -}); + }); -test('.except() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', ['title']) - .toJSON() - .find() - .then(function success(entries) { - - // assert.ok("entries" in result, 'Entries key present in the resultset'); - var flag = entries[0].every(function(entry) { - var _flag; - - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - _flag = true; - _flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); - } else { - _flag = true; - } - return (_flag && entry && (Object.keys(entry).length === 3 || Object.keys(entry).length === 2) && "reference" in entry && "uid" in entry); - }); - assert.ok(flag, 'entries with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail(".except() - For the reference - Array"); - assert.end(); + describe("Get Entries With Any Taxonomy Terms ($exists)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.exists("taxonomies.one").toJSON().find(); }); -}); -// Taxonomies Endpoint -test('Taxonomies Endpoint: Get Entries With One Term', function(assert) { - let Query = Stack.Taxonomies(); - Query - .where('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With One Term"); - assert.end(); - }) -}); + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); -test('Taxonomies Endpoint: Get Entries With Any Term ($in)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .containedIn('taxonomies.one', ['term_one', 'term_two']) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Any Term ($in)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Any Term ($or)', function(assert) { - let Query = Stack.Taxonomies(); - let Query1 = Stack.Taxonomies().where('taxonomies.one', 'term_one'); - let Query2 = Stack.Taxonomies().where('taxonomies.two', 'term_two'); - Query - .or(Query1, Query2) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Any Term ($or)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With All Terms ($and)', function(assert) { - let Query1 = Stack.Taxonomies().where('taxonomies.one', 'term_one'); - let Query2 = Stack.Taxonomies().where('taxonomies.two', 'term_two'); - let Query = Stack.Taxonomies(); - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With All Terms ($and)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Any Taxonomy Terms ($exists)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .exists('taxonomies.one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Any Taxonomy Terms ($exists)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Taxonomy Terms and Also Matching Its Children Term ($eq_below, level)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .equalAndBelow('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Taxonomy Terms and Also Matching Its Children Term ($eq_below, level)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Taxonomy Terms Children\'s and Excluding the term itself ($below, level)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .below('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Taxonomy Terms Children\'s and Excluding the term itself ($below, level)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Taxonomy Terms and Also Matching Its Parent Term ($eq_above, level)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .equalAndAbove('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Taxonomy Terms and Also Matching Its Parent Term ($eq_above, level)"); - assert.end(); - }) -}) - -test('Taxonomies Endpoint: Get Entries With Taxonomy Terms Parent and Excluding the term itself ($above, level)', function(assert) { - let Query = Stack.Taxonomies(); - Query - .above('taxonomies.one', 'term_one_child') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Taxonomies Endpoint: Get Entries With Taxonomy Terms Parent and Excluding the term itself ($above, level)"); - assert.end(); - }) -}) - -//Content Type end point -test('CT Taxonomies Query: Get Entries With One Term', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .where('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With One Term"); - assert.end(); - }) -}); + describe("Get Entries With Taxonomy Terms and Also Matching Its Children Term ($eq_below, level)", () => { + let entries; -test('CT Taxonomies Query: Get Entries With Any Term ($in)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .containedIn('taxonomies.one', ['term_one', 'term_two']) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Any Term ($in)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Any Term ($or)', function(assert) { - let Query = Stack.ContentType('source').Query(); - let Query1 = Stack.ContentType('source').Query().where('taxonomies.one', 'term_one'); - let Query2 = Stack.ContentType('source').Query().where('taxonomies.two', 'term_two'); - Query - .or(Query1, Query2) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Any Term ($or)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With All Terms ($and)', function(assert) { - let Query1 = Stack.ContentType('source').Query().where('taxonomies.one', 'term_one'); - let Query2 = Stack.ContentType('source').Query().where('taxonomies.two', 'term_two'); - let Query = Stack.ContentType('source').Query(); - Query - .and(Query1, Query2) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With All Terms ($and)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Any Taxonomy Terms ($exists)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .exists('taxonomies.one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Any Taxonomy Terms ($exists)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Taxonomy Terms and Also Matching Its Children Term ($eq_below, level)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .equalAndBelow('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Taxonomy Terms and Also Matching Its Children Term ($eq_below, level)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Taxonomy Terms Children\'s and Excluding the term itself ($below, level)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .below('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Taxonomy Terms Children\'s and Excluding the term itself ($below, level)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Taxonomy Terms and Also Matching Its Parent Term ($eq_above, level)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .equalAndAbove('taxonomies.one', 'term_one') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Taxonomy Terms and Also Matching Its Parent Term ($eq_above, level)"); - assert.end(); - }) -}) - -test('CT Taxonomies Query: Get Entries With Taxonomy Terms Parent and Excluding the term itself ($above, level)', function(assert) { - let Query = Stack.ContentType('source').Query(); - Query - .above('taxonomies.one', 'term_one_child') - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("CT Taxonomies Query: Get Entries With Taxonomy Terms Parent and Excluding the term itself ($above, level)"); - assert.end(); - }) -}) -test('Variants in entry', function (assert) { - let Query = Stack.ContentType('source').Query(); - Query - .variants(['variant_entry_1', 'variant_entry_2']) - .toJSON() - .find() - .then(entries => { - assert.ok(entries[0].length, 'Variant entries present in the resultset'); - assert.end(); - }, err => { - console.error("error :", err); - assert.fail("Variant Entries are not present in the CT"); - assert.end(); - }) -}); \ No newline at end of file + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.equalAndBelow("taxonomies.one", "term_one") + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + + describe("Get Entries With Taxonomy Terms Children's and Excluding the term itself ($below, level)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.below("taxonomies.one", "term_one") + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + + describe("Get Entries With Taxonomy Terms and Also Matching Its Parent Term ($eq_above, level)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.equalAndAbove("taxonomies.one", "term_one") + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + + describe("Get Entries With Taxonomy Terms Parent and Excluding the term itself ($above, level)", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.above("taxonomies.one", "term_one_child") + .toJSON() + .find(); + }); + + test("Should return entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + }); + describe("Variants Tests", () => { + describe("Variants in entry", () => { + let entries; + + beforeAll(async () => { + const Query = Stack.ContentType("source").Query(); + entries = await Query.variants(["variant_entry_1", "variant_entry_2"]) + .toJSON() + .find(); + }); + + test("Should return variant entries in the resultset", () => { + expect(entries[0].length).toBeTruthy(); + }); + }); + }); + }); +}); diff --git a/test/entry/findone-result-wrapper.js b/test/entry/findone-result-wrapper.js index 1ff2171a..af8e7774 100755 --- a/test/entry/findone-result-wrapper.js +++ b/test/entry/findone-result-wrapper.js @@ -1,778 +1,930 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const test = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const Utils = require('./utils.js'); -const init = require('../config.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const Utils = require("./utils.js"); +const init = require("../config.js"); const contentTypes = init.contentTypes; let Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - -test('findOne: default .findOne()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: default .findOne()"); - assert.end(); - }); -}); - -/*! - * SORTING - * !*/ -test('findOne: .ascending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - - Query - .ascending(field) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .ascending()"); - assert.end(); - }); -}); - -test('findOne: .descending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'created_at'; - - Query - .descending(field) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .descending()"); - assert.end(); - }); -}); - - -/*! - * COMPARISION - * !*/ -test('findOne: .lessThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - Query - .lessThan(field, value) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] < value), 'Entry num_field having value less than ' + value + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .lessThan()"); - assert.end(); - }); -}); - -test('findOne: .lessThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - Query - .lessThanOrEqualTo(field, value) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] <= value), 'Entry num_field having value less than or equal to ' + value + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .lessThanOrEqualTo()"); - assert.end(); - }); -}); - -test('findOne: .greaterThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 6; - - Query - .greaterThan(field, value) - .ascending(field) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] > value), 'Entry num_field having value greater than ' + value + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .greaterThan()"); - assert.end(); - }); -}); - -test('findOne: .greaterThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - - Query - .greaterThanOrEqualTo(field, value) - .descending(field) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] >= value), 'Entry num_field having value greater than ' + value + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .greaterThanOrEqualTo()"); - assert.end(); - }); -}); - -test('findOne: .notEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 6; - - Query - .notEqualTo(field, value) - .descending(field) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] !== value), 'Entry num_field having value is not equal to ' + value + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .notEqualTo()"); - assert.end(); - }); -}); - - -/*! - * Array/Subset - * !*/ - -test('findOne: .containedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2"]; - - Query - .containedIn('title', _in) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['title'] && ~_in.indexOf(entry['title'])), 'Entry title exists from the available options ' + _in.join(', ') + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .containedIn()"); - assert.end(); - }); -}); - -test('findOne: .notContainedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1"]; - - Query - .notContainedIn('title', _in) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['title'] && _in.indexOf(entry['title']) === -1), 'Entry title not exists from the available options ' + _in.join(', ') + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("findOne: .notContainedIn() :", err); - assert.deepEqual(err, { error_code: 141, error_message: 'The requested entry doesn\'t exist.' }, "No entry found"); - assert.end(); - }); -}); - - -/*! - *Element(exists) - * !*/ - -test('findOne: .exists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "boolean"; - - Query - .exists(queryField) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && typeof entry[queryField] !== 'undefined'), 'Entry having the ' + queryField + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .exists()"); - assert.end(); - }); -}); - -test('findOne: .notExists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "isspecial"; - - Query - .notExists(queryField) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && typeof entry[queryField] === 'undefined'), 'Entry having the ' + queryField + '.'); - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("findOne: .notExists():", err); - assert.deepEqual(err, { error_code: 141, error_message: 'The requested entry doesn\'t exist.' }, "No entry found"); - assert.end(); - }); -}); - - -// Pagination -test('findOne: .skip()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .toJSON() - .find() - .then(function success(allEntries) { - assert.ok(allEntries.length, 'entry key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .skip(1) - .toJSON() - .findOne() - .then(function result(entry) { - assert.deepEqual(allEntries[0][1], entry, 'Element matched.'); - assert.end(); - }, function error(err) { - console.error("error :", err); - assert.fail("findOne: .skip()"); - assert.end(); - }); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .skip()"); - assert.end(); - }); -}); - - - -// Logical -test('findOne: .or() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().containedIn('title', ['source1']); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', 'false'); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .or(Query1, Query2) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok((entry && entry['uid'] && entry['locale'] && entry['publish_details']), 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .or() - Query Objects"); - assert.end(); - }); -}); - -test('findOne: .and() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().containedIn('title', ['source1']); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .and(Query1, Query2) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok(entry && entry.uid && entry.locale && entry.publish_details, 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .and() - Query Objects"); - assert.end(); - }); -}); - - - -// Custom query -test('findOne: .query() - Raw query', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .query({ "$or": [{ "title": "source1" }, { "boolean": "false" }] }) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok(entry && entry.uid && entry.locale && entry.publish_details, 'Entry should have uid, publish_details, locale.'); - assert.ok(~(entry.title === 'source1' || entry.boolean === true), '$OR condition satisfied'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .query() - Raw query"); - assert.end(); - }); -}); - - -// tags -test('findOne: .tags()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - tags = ["tag1", "tag2"]; - - Query - .tags(tags) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok(entry && entry.uid && entry.locale && entry.publish_details, 'Entry should have uid, publish_details, locale.'); - assert.equal((Utils.arrayPresentInArray(tags, entry.tags) > 0), true, 'Tags specified are found in result set'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .tags()"); - assert.end(); - }); -}); - - -// search -test('findOne: .search()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .search('source1') - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok(entry && entry.uid && entry.locale && entry.publish_details, 'Entry should have uid, publish_details, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .search()"); - assert.end(); - }); -}); - - -// search -test('findOne: .regex()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'title', - regex = { - pattern: '^source', - options: 'i' - }; - - Query - .regex(field, regex.pattern, regex.options) - .toJSON() - .findOne() - .then(function success(entry) { - assert.ok(entry && entry.uid && entry.locale && entry.publish_details, 'Entry should have uid, publish_details, locale.'); - assert.ok((new RegExp(regex.pattern, regex.options).test(entry[field])), "regexp satisfied"); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .regex()"); - assert.end(); - }); -}); - - -test('findOne: without fallback', function(assert) { - var _in = ['ja-jp'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .toJSON() - .findOne() - .then((entry) => { - var _entries = (_in.indexOf(entry['publish_details']['locale']) != -1); - assert.equal(_entries, true, "Publish content fallback"); - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('findOne: fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .includeFallback() - .toJSON() - .findOne() - .then((entry) => { - var _entries = (_in.indexOf(entry['publish_details']['locale']) != -1); - assert.equal(_entries, true, "Publish content fallback"); - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -// includeReference -test('findOne: .includeReference() - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .toJSON() - .findOne() - .then(function success(entry) { - assert.equal((entry && entry['reference'] && typeof entry['reference'] === 'object'), true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeReference() - String"); - assert.end(); - }); -}); - -test('findOne: .includeReference() - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference(['reference', 'other_reference']) - .toJSON() - .findOne() - .then(function success(entry) { - assert.equal((entry && entry.reference && typeof entry.reference === 'object' && entry.other_reference && typeof entry.other_reference === 'object'), true, 'all the present reference and other reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeReference() - Array"); - assert.end(); - }); -}); - - -// includeSchema -test('findOne: .includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .toJSON() - .findOne() - .then(function success(entry, schema) { - // console.log("result : ", Object.keys(result || {})); - assert.ok(entry, 'entry present in the resultset'); - //assert.ok(schema, 'Schema is not present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeSchema()"); - assert.end(); - }); -}); - -// includeContentType -test('findOne: .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeContentType() - .toJSON() - .findOne() - .then(function success(entry, contentType) { - // console.log("result : ", entry, contentType); - assert.ok(entry, 'entry present in the resultset'); - assert.ok((typeof contentType === "undefined"), 'ContentType is not present.'); - // assert.ok((contentType.uid === "source"), 'ContentType is title matched.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeContentType()"); - assert.end(); - }); -}); - -// includeSchema & includeContentType -test('findOne: includeSchema & .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .includeContentType() - .toJSON() - .findOne() - .then(function success(entry, contentType) { - // console.log("result : ", entry, contentType); - assert.ok(entry, 'entry present in the resultset'); - assert.ok((typeof contentType === "undefined"), 'ContentType is not present.'); - // assert.ok((contentType.uid === "source"), 'ContentType is title matched.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: includeSchema & .includeContentType()"); - assert.end(); - }); -}); - -// only -test('findOne: .only() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - assert.ok(flag, 'entry with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Single String Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('BASE', 'title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - assert.ok(flag, 'entry with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Multiple String Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - Array Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only(['title', 'url']) - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 3 && "title" in entry && "uid" in entry && "url" in entry); - assert.ok(flag, 'entry with the field title,url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Array Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .includeReference('reference') - .only('BASE', 'reference') - .only('reference', 'title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry['reference'].every(function(reference) { - return (reference && "title" in reference && "uid" in reference); - }); +describe("FindOne Tests", () => { + // Setup - Initialize the Contentstack Stack Instance + beforeAll((done) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(done, 1000); + }); + + describe("Default FindOne", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + // SORTING TESTS + describe("Sorting", () => { + describe("Ascending", () => { + let entry; + let error = null; + const field = "updated_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.ascending(field).toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("Descending", () => { + let entry; + const field = "created_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.descending(field).toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + }); + + // COMPARISON TESTS + describe("Comparison", () => { + describe("lessThan", () => { + let entry; + let error = null; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.lessThan(field, value).toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + + test("num_field should be less than specified value", () => { + expect(entry[field]).toBeLessThan(value); + }); + }); + + describe("lessThanOrEqualTo", () => { + let entry; + let error = null; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.lessThanOrEqualTo(field, value).toJSON().findOne(); + }); + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + test("num_field should be less than or equal to specified value", () => { + expect(entry[field]).toBeLessThanOrEqual(value); + }); + }); + + describe("greaterThan", () => { + let entry; + let error = null; + const field = "num_field"; + const value = 6; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.greaterThan(field, value) + .ascending(field) + .toJSON() + .findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + + test("num_field should be greater than specified value", () => { + expect(entry[field]).toBeGreaterThan(value); + }); + }); + + describe("greaterThanOrEqualTo", () => { + let entry; + let error = null; + const field = "num_field"; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.greaterThanOrEqualTo(field, value) + .descending(field) + .toJSON() + .findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + + test("num_field should be greater than or equal to specified value", () => { + expect(entry[field]).toBeGreaterThanOrEqual(value); + }); + }); + + describe("notEqualTo", () => { + let entry; + let error = null; + const field = "num_field"; + const value = 6; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.notEqualTo(field, value) + .descending(field) + .toJSON() + .findOne(); + }); + + test("num_field should not be equal to specified value", () => { + expect(entry[field]).not.toBe(value); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + }); + + // ARRAY/SUBSET TESTS + describe("Array/Subset", () => { + describe("containedIn", () => { + let entry; + let error = null; + const _in = ["source1", "source2"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.containedIn("title", _in).toJSON().findOne(); + }); + + test("Entry title should be in the specified values", () => { + expect(_in).toContain(entry.title); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("notContainedIn", () => { + let entry; + let error = null; + const _in = ["source1"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.notContainedIn("title", _in).toJSON().findOne(); + }); + + test("Should either return an entry with matching criteria or an expected error", () => { + if (entry) { + expect(entry.title).toBeDefined(); + expect(_in).not.toContain(entry.title); + } else { + expect(error).toEqual({ + error_code: 141, + error_message: "The requested entry doesn't exist.", + }); + } + }); + + test("If entry exists, it should have uid", () => { + if (entry) { + expect(entry.uid).toBeDefined(); + } + }); + + test("If entry exists, it should have locale", () => { + if (entry) { + expect(entry.locale).toBeDefined(); + } + }); + + test("If entry exists, it should have publish_details", () => { + if (entry) { + expect(entry.publish_details).toBeDefined(); + } + }); + }); + }); + + // ELEMENT EXISTS TESTS + describe("Element Existence", () => { + describe("exists", () => { + let entry; + let error = null; + const queryField = "boolean"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.exists(queryField).toJSON().findOne(); + }); + + test("Entry should have the queried field", () => { + expect(typeof entry[queryField]).not.toBe("undefined"); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("notExists", () => { + let entry; + let error = null; + const queryField = "isspecial"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.notExists(queryField).toJSON().findOne(); + }); + + test("Should handle either success or error case", () => { + if (entry) { + expect(typeof entry[queryField]).toBe("undefined"); + } else { + expect(error).toEqual({ + error_code: 141, + error_message: "The requested entry doesn't exist.", + }); + } + }); + + test("If entry exists, it should have uid", () => { + if (entry) { + expect(entry.uid).toBeDefined(); + } + }); + + test("If entry exists, it should have locale", () => { + if (entry) { + expect(entry.locale).toBeDefined(); + } + }); + + test("If entry exists, it should have publish_details", () => { + if (entry) { + expect(entry.publish_details).toBeDefined(); + } + }); + }); + }); + describe("Pagination", () => { + describe("skip", () => { + let allEntries; + let skippedEntry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + allEntries = await Query.toJSON().find(); + + const skipQuery = Stack.ContentType(contentTypes.source).Query(); + skippedEntry = await skipQuery.skip(1).toJSON().findOne(); + }); + + test("Should have entries in the result set", () => { + expect(allEntries.length).toBeTruthy(); + }); + + test("Should get correct skipped entry", () => { + expect(skippedEntry).toEqual(allEntries[0][1]); + }); + }); + }); + + describe("Logical Operations", () => { + describe("OR Query Objects", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .containedIn("title", ["source1"]); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", "false"); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entry = await Query.or(Query1, Query2).toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("AND Query Objects", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .containedIn("title", ["source1"]); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entry = await Query.and(Query1, Query2).toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("Raw Query", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.query({ + $or: [{ title: "source1" }, { boolean: "false" }], + }) + .toJSON() + .findOne(); + }); + + test("Entry should satisfy OR condition", () => { + expect( + entry.title === "source1" || entry.boolean === false + ).toBeTruthy(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + }); + + describe("Tags", () => { + let entry; + let error = null; + const tags = ["tag1", "tag2"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.tags(tags).toJSON().findOne(); + }); + + test("Tags specified should be found in the result", () => { + expect(Utils.arrayPresentInArray(tags, entry.tags) > 0).toBe(true); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("Search", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.search("source1").toJSON().findOne(); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("Regex", () => { + let entry; + let error = null; + const field = "title"; + const regex = { + pattern: "^source", + options: "i", + }; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.regex(field, regex.pattern, regex.options) + .toJSON() + .findOne(); + }); + + test("Entry field should match the regex pattern", () => { + const regExp = new RegExp(regex.pattern, regex.options); + expect(regExp.test(entry[field])).toBe(true); + }); + + test("Should return an entry with uid, locale, publish_details", () => { + expect(entry).toBeDefined(); + expect(entry["uid"]).toBeDefined(); + expect(entry["locale"]).toBeDefined(); + expect(entry["publish_details"]).toBeDefined(); + }); + }); + + describe("Localization", () => { + describe("Without Fallback", () => { + let entry; + let error = null; + const _in = ["ja-jp"]; + + beforeAll(async () => { + entry = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have correct locale in publish_details", () => { + expect(_in).toContain(entry.publish_details.locale); + }); + }); + + describe("With Fallback", () => { + let entry; + let error = null; + const _in = ["ja-jp", "en-us"]; + + beforeAll(async () => { + entry = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .includeFallback() + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have locale from allowed fallback list", () => { + expect(_in).toContain(entry.publish_details.locale); + }); + }); + }); + describe("Including References", () => { + describe("includeReference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("All present references should be included as objects", () => { + expect( + entry && entry["reference"] && typeof entry["reference"] === "object" + ).toBe(true); + }); + }); + + describe("includeReference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference(["reference", "other_reference"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("All present references should be included as objects", () => { + const condition = + entry && + entry["reference"] && + typeof entry["reference"] === "object" && + entry.other_reference && + typeof entry.other_reference === "object"; + expect(condition).toBe(true); + }); + }); + }); + + describe("Including Schema", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeSchema().toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + }); + + describe("Including ContentType", () => { + let entry; + let contentType; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + [entry, contentType] = await new Promise((resolve, reject) => { + Query.includeContentType() + .toJSON() + .findOne() + .then((entry, contentType) => resolve([entry, contentType]), reject); + }); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("ContentType should not be present", () => { + expect(typeof contentType).toBe("undefined"); + }); + }); + + describe("Including Schema and ContentType", () => { + let entry; + let contentType; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + [entry, contentType] = await new Promise((resolve, reject) => { + Query.includeSchema() + .includeContentType() + .toJSON() + .findOne() + .then((entry, contentType) => resolve([entry, contentType]), reject); + }); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("ContentType should not be present", () => { + expect(typeof contentType).toBe("undefined"); + }); + }); + + describe("Field Selection - Only", () => { + describe("only - Single String Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only("title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should only contain title and uid fields", () => { + expect(Object.keys(entry).length).toBe(2); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - Multiple String Parameters", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only("BASE", "title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should only contain title and uid fields", () => { + expect(Object.keys(entry).length).toBe(2); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - Array Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only(["title", "url"]).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should contain title, url, and uid fields", () => { + expect(Object.keys(entry).length).toBe(3); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("url"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - For reference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", "reference") + .only("reference", "title") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Reference fields should be properly filtered", () => { + let hasProperReferences = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + hasProperReferences = entry["reference"].every( + (ref) => ref && "title" in ref && "uid" in ref + ); + } else { + hasProperReferences = true; // No references or empty references is valid + } + expect(hasProperReferences).toBe(true); + }); + }); + + describe("only - For reference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .only("reference", ["title"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should have only specified fields", () => { + let hasProperReferences = false; + if (entry && entry["reference"]) { + if (Array.isArray(entry["reference"])) { + if (entry["reference"].length === 0) { + hasProperReferences = true; } else { - flag = true - } - assert.equal(flag, true, 'Entry has the reference with only paramteres.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - For the reference - String"); - assert.end(); - }); -}); - -test('findOne: .only() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', ['title']) - .toJSON() - .findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference']) { - if (entry['reference'].length) { - if (entry['reference'].length === 0){ - flag = true - } else { - flag = entry['reference'].every(function(reference) { - return (reference && "title" in reference && "uid" in reference); - }); - } - } else { - flag = true - } - } else { - flag = true - } - assert.equal(flag, true, 'Entry do not have the reference with only paramteres.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - For the reference - Array"); - assert.end(); - }); -}); - -// except -test('findOne: .except() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry)); - assert.ok(flag, 'entry without the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - Single String Parameter"); - assert.end(); - }); -}); - -test('findOne: .except() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('BASE', 'title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry)); - assert.ok(flag, 'entry without the field title, url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - Multiple String Parameter"); - assert.end(); - }); -}); - -test('findOne: .except() - Array of String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except(['title', 'url']) - .toJSON() - .findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry) && !("url" in entry)); - assert.ok(flag, 'entry without the field title, url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail(""); - assert.end(); - }); -}); - -test('findOne: .except() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', 'reference') - .except('reference', 'title') - .toJSON() - .findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry['reference'].every(function(reference) { - return (reference && !("title" in reference)); - }); + hasProperReferences = entry["reference"].every( + (ref) => ref && "title" in ref && "uid" in ref + ); } - assert.ok(flag, 'entry with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - For the reference - String"); - assert.end(); - }); + } else { + hasProperReferences = true; + } + } else { + hasProperReferences = true; + } + expect(hasProperReferences).toBe(true); + }); + }); + }); + + describe("Field Selection - Except", () => { + describe("except - Single String Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except("title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the excluded field", () => { + expect(entry).not.toHaveProperty("title"); + }); + }); + + describe("except - Multiple String Parameters", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except("BASE", "title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the excluded field", () => { + expect(entry).not.toHaveProperty("title"); + }); + }); + + describe("except - Array of String Parameters", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except(["title", "url"]).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the first excluded field", () => { + expect(entry).not.toHaveProperty("title"); + }); + + test("Entry should not contain the second excluded field", () => { + expect(entry).not.toHaveProperty("url"); + }); + }); + + describe("except - For the reference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", "reference") + .except("reference", "title") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should not contain the excluded field", () => { + let hasProperExclusions = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + hasProperExclusions = entry["reference"].every( + (ref) => ref && !("title" in ref) + ); + } else { + // No references is valid for this test + hasProperExclusions = true; + } + expect(hasProperExclusions).toBe(true); + }); + }); + + describe("except - For the reference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .except("reference", ["title"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should not contain the excluded field", () => { + let hasProperExclusions = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + hasProperExclusions = entry["reference"].every( + (ref) => ref && !("title" in ref) + ); + } else { + hasProperExclusions = true; + } + expect(hasProperExclusions).toBe(true); + }); + }); + }); }); - -test('findOne: .except() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', ['title']) - .toJSON() - .findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry['reference'].every(function(reference) { - return (reference && !("title" in reference)); - }); - } - assert.ok(flag, 'entry with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - For the reference - Array"); - assert.end(); - }); -}); \ No newline at end of file diff --git a/test/entry/findone.js b/test/entry/findone.js index 130d336e..e63d74be 100755 --- a/test/entry/findone.js +++ b/test/entry/findone.js @@ -1,777 +1,907 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const test = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const Utils = require('./utils.js'); -const init = require('../config.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const Utils = require("./utils.js"); +const init = require("../config.js"); const contentTypes = init.contentTypes; let Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - -test('findOne: default .toJSON().findOne()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - Query - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: default .toJSON().findOne()"); - assert.end(); - }); -}); - -/*! - * SORTING - * !*/ -test('findOne: .ascending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'created_at'; - - Query - .ascending(field) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .ascending()"); - assert.end(); - }); -}); - -test('findOne: .descending()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'created_at'; - - Query - .descending(field) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .descending()"); - assert.end(); - }); -}); - - -/*! - * COMPARISION - * !*/ -test('findOne: .lessThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - value = 11; - Query - .lessThan('num_field', value) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.num_field < value), 'Entry num_field having value less than ' + value + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .lessThan()"); - assert.end(); - }); -}); - -test('findOne: .lessThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - value = 11; - Query - .lessThanOrEqualTo('num_field', value) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.num_field <= value), 'Entry num_field having value less than or equal to ' + value + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .lessThanOrEqualTo()"); - assert.end(); - }); -}); - -test('findOne: .greaterThan()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - - Query - .greaterThan('num_field', value) - .ascending(field) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] > value), 'Entry num_field having value greater than ' + value + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .greaterThan()"); - assert.end(); - }); -}); - -test('findOne: .greaterThanOrEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 11; - - Query - .greaterThanOrEqualTo('num_field', value) - .descending(field) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] >= value), 'Entry num_field having value greater than ' + value + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error : ", err); - assert.fail("findOne: .greaterThanOrEqualTo()"); - assert.end(); - }); -}); - -test('findOne: .notEqualTo()', function(assert) { - var Query = Stack.ContentType(contentTypes.numbers_content_type).Query(), - field = 'num_field', - value = 6; - - Query - .notEqualTo('num_field', value) - .descending(field) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry[field] !== value), 'Entry num_field having value is not equal to ' + value + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error : ", err); - assert.fail("findOne: .notEqualTo()"); - assert.end(); - }); -}); - - -/*! - * Array/Subset - * !*/ - -test('findOne: .containedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2"]; - - Query - .containedIn('title', _in) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.title && ~_in.indexOf(entry.title)), 'Entry title exists from the available options ' + _in.join(', ') + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .containedIn()"); - assert.end(); - }); -}); - -test('findOne: .notContainedIn()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - _in = ["source1", "source2", "source3", "source4"]; - - Query - .notContainedIn('title', _in) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.title && _in.indexOf(entry.title) === -1), 'Entry title not exists from the available options ' + _in.join(', ') + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.deepEqual(err, { error_code: 141, error_message: 'The requested entry doesn\'t exist.' }, "No entry found"); - assert.end(); - }); -}); - - -/*! - *Element(exists) - * !*/ - -test('findOne: .exists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "boolean"; - - Query - .exists(queryField) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && typeof entry[queryField] !== 'undefined'), 'Entry having the ' + queryField + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .exists()"); - assert.end(); - }); -}); - -test('findOne: .notExists()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - queryField = "isspecial"; - - Query - .notExists(queryField) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && typeof entry[queryField] === 'undefined'), 'Entry having the ' + queryField + '.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.deepEqual(err, { error_code: 141, error_message: 'The requested entry doesn\'t exist.' }, "No entry found"); - assert.end(); - }); -}); - - -// Pagination -test('findOne: .skip()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .toJSON().find() - .then(function success(allEntries) { - assert.ok(allEntries.length, 'entry key present in the resultset'); - Stack - .ContentType(contentTypes.source) - .Query() - .skip(1) - .toJSON().findOne() - .then(function result(entry) { - assert.deepEqual(allEntries[0][1], entry, 'Element matched.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .skip()"); - assert.end(); - }); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .skip()"); - assert.end(); - }); -}); - -// Logical -test('findOne: .or() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().containedIn('title', ['source1', 'source2']); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .or(Query1, Query2) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && (~(entry.title === 'source1' || entry.boolean === true))), 'Entry satisfies the $OR condition'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .or() - Query Objects"); - assert.end(); - }); -}); - -test('findOne: .and() - Query Objects', function(assert) { - var Query1 = Stack.ContentType(contentTypes.source).Query().where('title', 'source1'); - var Query2 = Stack.ContentType(contentTypes.source).Query().where('boolean', true); - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .and(Query1, Query2) - .toJSON().findOne() - .then(function success(entry) { - assert.ok(~(entry.title === 'source1' && entry.boolean === true), 'Entry satisfies the $AND operation.'); - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .and() - Query Objects"); - assert.end(); - }); -}); - -// Custom query -test('findOne: .query() - Raw query', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .query({ "$or": [{ "title": "source1" }, { "boolean": "false" }] }) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.ok(~(entry.title === 'source1' || entry.boolean === true), '$OR condition satisfied'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .query() - Raw query"); - assert.end(); - }); -}); - - -// tags -test('findOne: .tags()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - tags = ["tag1", "tag2"]; - - Query - .tags(tags) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.equal((Utils.arrayPresentInArray(tags, entry.tags) > 0), true, 'Tags specified are found in result set'); - assert.end(); - }, function error(err) { - console.error("Error :",err); - assert.fail("findOne: .tags()"); - assert.end(); - }); -}); - -//search -test('findOne: .search()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .search('source1') - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .search()"); - assert.end(); - }); -}); - - -// search -test('findOne: .regex()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'title', - regex = { - pattern: '^source', - options: 'i' - }; - - Query - .regex(field, regex.pattern, regex.options) - .toJSON().findOne() - .then(function success(entry) { - assert.ok((entry && entry.uid && entry.locale && entry.publish_details), 'Entry should have publish_details, uid, locale.'); - assert.ok((new RegExp(regex.pattern, regex.options).test(entry[field])), "regexp satisfied"); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .regex()"); - assert.end(); - }); -}); - -test('findOne: without fallback', function(assert) { - var _in = ['ja-jp'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .toJSON() - .findOne() - .then((entry) => { - var _entries = (_in.indexOf(entry['publish_details']['locale']) != -1); - assert.equal(_entries, true, "Publish content fallback"); - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -test('findOne: fallback', function(assert) { - var _in = ['ja-jp', 'en-us'] - Stack.ContentType(contentTypes.source).Query().language('ja-jp') - .toJSON() - .includeFallback() - .findOne() - .then((entry) => { - var _entries = (_in.indexOf(entry['publish_details']['locale']) != -1); - assert.equal(_entries, true, "Publish content fallback"); - assert.end(); - }).catch((error) => { - assert.fail("Entries default .find() fallback catch", error.toString()); - assert.end(); - }) -}) - -// includeReference -test('findOne: .includeReference() - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .toJSON().findOne() - .then(function success(entry) { - assert.equal((entry && entry.reference && typeof entry.reference === 'object'), true, 'all the present reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeReference() - String"); - assert.end(); - }); -}); - -test('findOne: .includeReference() - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference(['reference', 'other_reference']) - .toJSON().findOne() - .then(function success(entry) { - assert.equal((entry && entry.reference && typeof entry.reference === 'object' && entry.other_reference && typeof entry.other_reference === 'object'), true, 'all the present reference and other reference are included'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeReference() - Array"); - assert.end(); - }); -}); - - -// includeSchema -test('findOne: .includeSchema()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .toJSON() - .findOne() - .then(function success(entry) { - // console.log("result : ", Object.keys(result || {})); - assert.ok(entry, 'Entry present in the resultset'); - //assert.ok(entry.length, 'Schema key present in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeSchema()"); - assert.end(); - }); -}); - -// includeContentType -test('findOne: .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeContentType() - .toJSON() - .findOne() - .then(function success(entry, contentType) { - // console.log("result : ", entry, contentType); - assert.ok(entry, 'entry present in the resultset'); - assert.ok((typeof contentType === "undefined"), 'ContentType is not present.'); - // assert.ok((contentType.uid === "source"), 'ContentType is title matched.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .includeContentType()"); - assert.end(); - }); -}); - -// includeSchema & includeContentType -test('findOne: includeSchema & .includeContentType()', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeSchema() - .includeContentType() - .toJSON() - .findOne() - .then(function success(entry, contentType) { - // console.log("result : ", entry, contentType); - assert.ok(entry, 'entry present in the resultset'); - assert.ok((typeof contentType === "undefined"), 'ContentType is not present.'); - // assert.ok((contentType.uid === "source"), 'ContentType is title matched.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: includeSchema & .includeContentType()"); - assert.end(); - }); -}); - -// only -test('findOne: .only() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('title') - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - assert.ok(flag, 'entry with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Single String Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only('BASE', 'title') - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 2 && "title" in entry && "uid" in entry); - assert.ok(flag, 'entry with the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Multiple String Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - Array Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .only(['title', 'url']) - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && Object.keys(entry).length === 3 && "title" in entry && "url" in entry && "uid" in entry); - assert.ok(flag, 'entry with the field title,url in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - Array Parameter"); - assert.end(); - }); -}); - -test('findOne: .only() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', 'reference') - .only('reference', 'title') - .toJSON().findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry.reference.every(function(reference) { - return (reference && "title" in reference && "uid" in reference); - }); - } else { - flag = true - } - assert.equal(flag, true, 'Entry has the reference with only paramteres.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - For the reference - String"); - assert.end(); - }); -}); - -test('findOne: .only() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .only('reference', ['title']) - .toJSON().findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference']) { - if (entry['reference'].length) { - if (entry['reference'].length === 0){ - flag = true - } else { - flag = entry.reference.every(function(reference) { - return (reference && "title" in reference && "uid" in reference); - }); - } - }else { - flag = true - } +describe("FindOne Tests", () => { + // Setup - Initialize the Contentstack Stack Instance + beforeAll((done) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(done, 1000); + }); + + describe("Default FindOne", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("Sorting", () => { + describe("Ascending", () => { + let entry; + let error = null; + const field = "created_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.ascending(field).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("Descending", () => { + let entry; + let error = null; + const field = "created_at"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.descending(field).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + }); + + describe("Comparison", () => { + describe("lessThan", () => { + let entry; + let error = null; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.lessThan("num_field", value).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("num_field should be less than specified value", () => { + expect(entry.num_field).toBeLessThan(value); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("lessThanOrEqualTo", () => { + let entry; + let error = null; + const value = 11; + + beforeAll(async () => { + const Query = Stack.ContentType( + contentTypes.numbers_content_type + ).Query(); + entry = await Query.lessThanOrEqualTo("num_field", value) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("num_field should be less than or equal to specified value", () => { + expect(entry.num_field).toBeLessThanOrEqual(value); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + }); + + describe("Array/Subset", () => { + describe("containedIn", () => { + let entry; + let error = null; + const _in = ["source1", "source2"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.containedIn("title", _in).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry title should be in the specified values", () => { + expect(_in).toContain(entry.title); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("notContainedIn", () => { + let entry; + let error = null; + const _in = ["source1", "source2", "source3", "source4"]; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.notContainedIn("title", _in).toJSON().findOne(); + }); + + test("Should either return an entry or an expected error", () => { + if (entry) { + expect(entry).toBeDefined(); + expect(_in).not.toContain(entry.title); + expect(entry.uid).toBeDefined(); + expect(entry.locale).toBeDefined(); + expect(entry.publish_details).toBeDefined(); + } else { + expect(error).toEqual({ + error_code: 141, + error_message: "The requested entry doesn't exist.", + }); + } + }); + }); + }); + + describe("Element Existence", () => { + describe("exists", () => { + let entry; + let error = null; + const queryField = "boolean"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.exists(queryField).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have the queried field", () => { + expect(typeof entry[queryField]).not.toBe("undefined"); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("notExists", () => { + let entry; + let error = null; + const queryField = "isspecial"; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.notExists(queryField).toJSON().findOne(); + }); + + test("Should either have entry without field or proper error", () => { + if (entry) { + expect(typeof entry[queryField]).toBe("undefined"); + expect(entry.uid).toBeDefined(); + expect(entry.locale).toBeDefined(); + expect(entry.publish_details).toBeDefined(); + } else { + expect(error).toEqual({ + error_code: 141, + error_message: "The requested entry doesn't exist.", + }); + } + }); + }); + }); + + describe("Pagination", () => { + describe("skip", () => { + let allEntries; + let skippedEntry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + allEntries = await Query.toJSON().find(); + + const SkipQuery = Stack.ContentType(contentTypes.source).Query(); + skippedEntry = await SkipQuery.skip(1).toJSON().findOne(); + }); + + test("Should have entries in the result set", () => { + expect(allEntries.length).toBeTruthy(); + }); + + test("Should get correct skipped entry", () => { + expect(skippedEntry).toEqual(allEntries[0][1]); + }); + }); + }); + + describe("Logical Operations", () => { + describe("OR Query Objects", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .containedIn("title", ["source1", "source2"]); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entry = await Query.or(Query1, Query2).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should satisfy the OR condition", () => { + const condition = + entry.title === "source1" || + entry.title === "source2" || + entry.boolean === true; + expect(condition).toBeTruthy(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("AND Query Objects", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query1 = Stack.ContentType(contentTypes.source) + .Query() + .where("title", "source1"); + const Query2 = Stack.ContentType(contentTypes.source) + .Query() + .where("boolean", true); + const Query = Stack.ContentType(contentTypes.source).Query(); + + entry = await Query.and(Query1, Query2).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should satisfy the AND condition", () => { + const condition = entry.title === "source1" && entry.boolean === true; + expect(condition).toBeTruthy(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + + describe("Raw Query", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.query({ + $or: [{ title: "source1" }, { boolean: "false" }], + }) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should satisfy the OR condition in raw query", () => { + const condition = entry.title === "source1" || entry.boolean === false; + expect(condition).toBeTruthy(); + }); + + test("Entry should have uid", () => { + expect(entry.uid).toBeDefined(); + }); + + test("Entry should have locale", () => { + expect(entry.locale).toBeDefined(); + }); + + test("Entry should have publish_details", () => { + expect(entry.publish_details).toBeDefined(); + }); + }); + }); + + describe("Localization", () => { + describe("Without Fallback", () => { + let entry; + let error = null; + const _in = ["ja-jp"]; + + beforeAll(async () => { + entry = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have correct locale in publish_details", () => { + expect(_in).toContain(entry.publish_details.locale); + }); + }); + + describe("With Fallback", () => { + let entry; + let error = null; + const _in = ["ja-jp", "en-us"]; + + beforeAll(async () => { + entry = await Stack.ContentType(contentTypes.source) + .Query() + .language("ja-jp") + .includeFallback() + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should have locale from allowed fallback list", () => { + expect(_in).toContain(entry.publish_details.locale); + }); + }); + }); + describe("Including References", () => { + describe("includeReference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("All present references should be included as objects", () => { + expect( + entry && entry.reference && typeof entry.reference === "object" + ).toBe(true); + }); + }); + + describe("includeReference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference(["reference", "other_reference"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("All present references should be included as objects", () => { + const condition = + entry && + entry.reference && + typeof entry.reference === "object" && + entry.other_reference && + typeof entry.other_reference === "object"; + expect(condition).toBe(true); + }); + }); + }); + + describe("Including Schema", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeSchema().toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + }); + + describe("Including ContentType", () => { + let entry; + let contentType; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + [entry, contentType] = await new Promise((resolve, reject) => { + Query.includeContentType() + .toJSON() + .findOne() + .then((entry, contentType) => resolve([entry, contentType]), reject); + }); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("ContentType should not be present", () => { + expect(typeof contentType).toBe("undefined"); + }); + }); + + describe("Including Schema and ContentType", () => { + let entry; + let contentType; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + [entry, contentType] = await new Promise((resolve, reject) => { + Query.includeSchema() + .includeContentType() + .toJSON() + .findOne() + .then((entry, contentType) => resolve([entry, contentType]), reject); + }); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("ContentType should not be present", () => { + expect(typeof contentType).toBe("undefined"); + }); + }); + + describe("Field Selection - Only", () => { + describe("only - Single String Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only("title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should only contain title and uid fields", () => { + expect(Object.keys(entry).length).toBe(2); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - Multiple String Parameters", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only("BASE", "title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should only contain title and uid fields", () => { + expect(Object.keys(entry).length).toBe(2); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - Array Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.only(["title", "url"]).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should contain title, url, and uid fields", () => { + expect(Object.keys(entry).length).toBe(3); + expect(entry).toHaveProperty("title"); + expect(entry).toHaveProperty("url"); + expect(entry).toHaveProperty("uid"); + }); + }); + + describe("only - For reference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", "reference") + .only("reference", "title") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should have only specified fields", () => { + let flag = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + flag = entry.reference.every( + (reference) => + reference && "title" in reference && "uid" in reference + ); + } else { + flag = true; + } + expect(flag).toBe(true); + }); + }); + + describe("only - For reference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .only("reference", ["title"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should have only specified fields", () => { + let flag = false; + if (entry && entry["reference"]) { + if (entry["reference"].length) { + if (entry["reference"].length === 0) { + flag = true; } else { - flag = true - } - assert.equal(flag, true, 'Entry has the reference with only paramteres.'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .only() - For the reference - Array"); - assert.end(); - }); -}); - -// except -test('findOne: .except() - Single String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('title') - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry)); - assert.ok(flag, 'entry without the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - Single String Parameter"); - assert.end(); - }); -}); - -test('findOne: .except() - Multiple String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except('BASE', 'title') - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry)); - assert.ok(flag, 'entry without the field title in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - Multiple String Parameter"); - assert.end(); - }); -}); - -test('findOne: .except() - Array of String Parameter', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .except(['title', 'file']) - .toJSON().findOne() - .then(function success(entry) { - var flag = (entry && !("title" in entry) && !("file" in entry)); - assert.ok(flag, 'entry without the field title, file in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - Array of String Parameter"); - assert.end(); - }); -}); - -test('findOne: .except() - For the reference - String', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', 'reference') - .except('reference', 'title') - .toJSON().findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); - } - assert.ok(flag, 'entry with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - For the reference - String"); - assert.end(); - }); -}); - -test('findOne: .except() - For the reference - Array', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .includeReference('reference') - .only('BASE', ['reference']) - .except('reference', ['title']) - .toJSON().findOne() - .then(function success(entry) { - var flag = false; - if (entry && entry['reference'] && typeof entry['reference'] === 'object') { - flag = entry.reference.every(function(reference) { - return (reference && !("title" in reference)); - }); + flag = entry.reference.every( + (reference) => + reference && "title" in reference && "uid" in reference + ); } - assert.ok(flag, 'entry with the field reference without title field in the resultset'); - assert.end(); - }, function error(err) { - console.error("Error :", err); - assert.fail("findOne: .except() - For the reference - Array"); - assert.end(); - }); -}); -/*! - * HTTP Error Handling - * !*/ - -test('findOne: should handle 422 Unprocessable Entity error', function(assert) { - const Query = Stack.ContentType("invalid_content_type").Query(); - - Query - .toJSON() - .findOne() - .then(function success() { - assert.fail("Expected 422 error but got a successful response."); - assert.end(); - }, function error(err) { - assert.equal(err.http_code, 422, 'Should return HTTP status 422.'); - assert.ok(err.http_message, 'Unprocessable Entity'); - assert.end(); - }); -}); - -test('findOne: should handle 412 Unauthorized error', function(assert) { - Stack.headers = { authorization: 'InvalidAPIKey' }; // Simulating an invalid API key - const Query = Stack.ContentType(contentTypes.source).Query(); - - Query - .toJSON() - .findOne() - .then(function success() { - assert.fail("Expected 412 error but got a successful response."); - assert.end(); - }, function error(err) { - assert.equal(err.http_code, 412, 'Should return HTTP status 412.'); - assert.ok(err.http_message, 'Precondition Failed.'); - assert.end(); - }); + } else { + flag = true; + } + } else { + flag = true; + } + expect(flag).toBe(true); + }); + }); + }); + + describe("Field Selection - Except", () => { + describe("except - Single String Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except("title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the title field", () => { + expect(entry).not.toHaveProperty("title"); + }); + }); + + describe("except - Multiple String Parameters", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except("BASE", "title").toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the title field", () => { + expect(entry).not.toHaveProperty("title"); + }); + }); + + describe("except - Array Parameter", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.except(["title", "file"]).toJSON().findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("Entry should not contain the title field", () => { + expect(entry).not.toHaveProperty("title"); + }); + + test("Entry should not contain the file field", () => { + expect(entry).not.toHaveProperty("file"); + }); + }); + + describe("except - For reference - String", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", "reference") + .except("reference", "title") + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should not contain the specified field", () => { + let flag = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + flag = entry.reference.every( + (reference) => reference && !("title" in reference) + ); + } + expect(flag).toBeTruthy(); + }); + }); + + describe("except - For reference - Array", () => { + let entry; + let error = null; + + beforeAll(async () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + entry = await Query.includeReference("reference") + .only("BASE", ["reference"]) + .except("reference", ["title"]) + .toJSON() + .findOne(); + }); + + test("Should return an entry", () => { + expect(entry).toBeDefined(); + }); + + test("References should not contain the specified field", () => { + let flag = false; + if ( + entry && + entry["reference"] && + typeof entry["reference"] === "object" + ) { + flag = entry.reference.every( + (reference) => reference && !("title" in reference) + ); + } + expect(flag).toBeTruthy(); + }); + }); + }); + + describe('HTTP Error Handling', () => { + describe('422 Unprocessable Entity Error', () => { + let success = false; + let error = null; + + beforeAll(async () => { + try { + const Query = Stack.ContentType("invalid_content_type").Query(); + await Query.toJSON().findOne(); + success = true; + } catch (err) { + error = err; + } + }); + + test("Should not succeed", () => { + expect(success).toBe(false); + }); + + test("Should return HTTP status 422", () => { + expect(error.http_code).toBe(422); + }); + + test("Should have appropriate error message", () => { + expect(error.http_message).toBeTruthy(); + }); + }); + + describe("412 Unauthorized Error", () => { + let success = false; + let error = null; + + beforeAll(async () => { + try { + Stack.headers = { authorization: "InvalidAPIKey" }; // Simulating an invalid API key + const Query = Stack.ContentType(contentTypes.source).Query(); + await Query.toJSON().findOne(); + success = true; + } catch (err) { + error = err; + } finally { + // Reset headers for subsequent tests + Stack.headers = {}; + } + }); + + test("Should not succeed", () => { + expect(success).toBe(false); + }); + + test("Should return HTTP status 412", () => { + expect(error.http_code).toBe(412); + }); + + test("Should have appropriate error message", () => { + expect(error.http_message).toBeTruthy(); + }); + }); + }); }); diff --git a/test/entry/spread.js b/test/entry/spread.js index b863c9c5..f6395c37 100755 --- a/test/entry/spread.js +++ b/test/entry/spread.js @@ -1,209 +1,286 @@ /** * Created by Aamod Pisat on 09-06-2017. */ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const test = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const init = require('../config.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); const contentTypes = init.contentTypes; -var Stack; -/* - * Initalise the Contentstack Instance - * */ -test('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); +let Stack; + +describe("Spread Method Tests", () => { + // Setup - Initialize the Contentstack Stack Instance + beforeAll((done) => { + Stack = Contentstack.Stack(init.stack); + Stack.setHost(init.host); + setTimeout(done, 1000); + }); -test('entries as first argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; + describe("Entries as first argument", () => { + const field = "updated_at"; - Query - .limit(1) + test("Should have entries", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.limit(1) .toJSON() .find() .spread(function success(entries) { - assert.ok(entries.length, 'Entries exists as first parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); + expect(entries.length).toBeTruthy(); }); -}); + }); + + test("Should maintain default sorting of descending updated_at", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.limit(1) + .toJSON() + .find() + .spread(function success(entries) { + if (entries && entries.length) { + let prev = entries[0][field]; + const _entries = entries.every((entry) => { + prev = entry[field]; + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } + }); + }); + }); + + describe("With entries and count argument", () => { + const field = "updated_at"; + + test("Should have entries as first parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .toJSON() + .find() + .spread((entries) => { + expect(entries.length).toBeTruthy(); + }); + }); + + test("Should have count as second parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .toJSON() + .find() + .spread((_, count) => { + expect(count).toBeTruthy(); + }); + }); + + test("Should maintain default sorting of descending updated_at", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .toJSON() + .find() + .spread((entries) => { + if (entries && entries.length) { + let prev = entries[0][field]; + const _entries = entries.every((entry) => { + prev = entry[field]; + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } + }); + }); + }); + + describe("With entries, schema and count argument (includeSchema first)", () => { + const field = "updated_at"; -test('with entries and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query + test("Should have entries as first parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeSchema() .includeCount() .toJSON() .find() - .spread(function success(entries, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(count, 'Count exists as second parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); + .spread((entries) => { + expect(entries.length).toBeTruthy(); }); -}); + }); -test('with entries, schema and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query - .includeSchema() + test("Should have schema as second parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeSchema() .includeCount() .toJSON() .find() - .spread(function success(entries, schema, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(schema, 'Schema exists as second parameter'); - assert.ok(count, 'Count exists as third parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); + .spread((_, schema) => { + expect(schema).toBeTruthy(); }); -}); + }); -test('with entries, schema and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query + test("Should have count as third parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeSchema() .includeCount() - .includeSchema() .toJSON() .find() - .spread(function success(entries, schema, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(schema, 'Schema exists as second parameter'); - assert.ok(count, 'Count exists as third parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.fail(err.message); - assert.end(); + .spread((_, __, count) => { + expect(count).toBeTruthy(); }); -}); + }); -test('with entries, content_type and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query - .includeContentType() + test("Should maintain default sorting of descending updated_at", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeSchema() .includeCount() .toJSON() .find() - .spread(function success(entries, contentType, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(contentType, 'ContentType exists as second parameter'); - assert.ok((contentType.uid === contentTypes.source), 'ContentType exists as second parameter'); - assert.ok(count, 'Count exists as third parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.end(); + .spread((entries) => { + if (entries && entries.length) { + let prev = entries[0][field]; + const _entries = entries.every((entry) => { + prev = entry[field]; + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } }); -}); + }); + }); -test('with entries, content_type and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query + describe("With entries, content_type and count argument (includeContentType first)", () => { + const field = "updated_at"; + + test("Should have entries as first parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeContentType() .includeCount() - .includeContentType() .toJSON() .find() - .spread(function success(entries, contentType, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(contentType, 'ContentType exists as second parameter'); - assert.ok((contentType.uid === contentTypes.source), 'ContentType exists as second parameter'); - assert.ok(count, 'Count exists as third parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.fail(err.message); - assert.end(); + .spread((entries) => { + expect(entries.length).toBeTruthy(); }); -}); + }); + + test("Should have contentType as second parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeContentType() + .includeCount() + .toJSON() + .find() + .spread((_, contentType) => { + expect(contentType).toBeTruthy(); + }); + }); -test('with entries, content_type|schema and count argument', function(assert) { - var Query = Stack.ContentType(contentTypes.source).Query(), - field = 'updated_at'; - Query + test("Should have correct contentType uid", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeContentType() .includeCount() + .toJSON() + .find() + .spread((_, contentType) => { + expect(contentType.uid).toBe(contentTypes.source); + }); + }); + + test("Should have count as third parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeContentType() + .includeCount() + .toJSON() + .find() + .spread((_, __, count) => { + expect(count).toBeTruthy(); + }); + }); + + test("Should maintain default sorting of descending updated_at", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeContentType() + .includeCount() + .toJSON() + .find() + .spread((entries) => { + if (entries && entries.length) { + let prev = entries[0][field]; + const _entries = entries.every((entry) => { + prev = entry[field]; + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } + }); + }); + }); + + describe("With entries, content_type|schema and count argument", () => { + const field = "updated_at"; + + test("Should have entries as first parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find() + .spread((entries) => { + expect(entries.length).toBeTruthy(); + }); + }); + + test("Should have contentType as second parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() .includeSchema() .includeContentType() .toJSON() .find() - .spread(function success(entries, contentType, count) { - assert.ok(entries.length, 'Entries exists as first parameter'); - assert.ok(contentType, 'ContentType exists as second parameter'); - assert.ok((contentType.uid === contentTypes.source), 'ContentType exists as second parameter'); - assert.ok(count, 'Count exists as third parameter'); - if (entries && entries.length) { - var prev = entries[0][field]; - var _entries = entries.every(function(entry) { - prev = entry[field]; - return (entry[field] <= prev); - }); - assert.equal(_entries, true, "default sorting of descending 'updated_at'"); - } - assert.end(); - }, function error(err) { - assert.fail(err.message); - assert.end(); - }); -}); \ No newline at end of file + .spread((_, contentType) => { + expect(contentType).toBeTruthy(); + }); + }); + + test("Should have correct contentType uid", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find() + .spread((_, contentType) => { + expect(contentType.uid).toBe(contentTypes.source); + }); + }); + + test("Should have count as third parameter", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find() + .spread((_, __, count) => { + expect(count).toBeTruthy(); + }); + }); + + test("Should maintain default sorting of descending updated_at", () => { + const Query = Stack.ContentType(contentTypes.source).Query(); + Query.includeCount() + .includeSchema() + .includeContentType() + .toJSON() + .find() + .spread((entries) => { + if (entries && entries.length) { + let prev = entries[0][field]; + const _entries = entries.every((entry) => { + prev = entry[field]; + return entry[field] <= prev; + }); + expect(_entries).toBe(true); + } + }); + }); + }); +}); diff --git a/test/index.js b/test/index.js index cd96d6b2..91d6debf 100755 --- a/test/index.js +++ b/test/index.js @@ -5,7 +5,7 @@ require('./entry/findone'); require('./entry/findone-result-wrapper'); require('./entry/spread'); -//require('./sync/sync-testcases'); +require('./sync/sync-testcases'); // Assets require('./asset/find'); diff --git a/test/live-preview/live-preview-test.js b/test/live-preview/live-preview-test.js index 7bd491d3..808e75d2 100644 --- a/test/live-preview/live-preview-test.js +++ b/test/live-preview/live-preview-test.js @@ -1,91 +1,69 @@ - 'use strict'; +const init = require("../config.js"); -const test = require('tape'); const Contentstack = require('../../dist/node/contentstack.js'); -test('should check for values initialized', function(assert) { +describe('Contentstack Live Preview Tests', () => { + test('should check for values initialized', () => { + const stack1 = Contentstack.Stack(init.stack) const stack = Contentstack.Stack({ - 'api_key': process.env.API_KEY, - 'delivery_token': process.env.DELIVERY_TOKEN, - 'environment': process.env.ENVIRONMENT + 'api_key': process.env.API_KEY, + 'delivery_token': process.env.DELIVERY_TOKEN, + 'environment': process.env.ENVIRONMENT }); + const livePreviewObject = stack.config.live_preview; - assert.equal(livePreviewObject.enable, false); - assert.equal(stack.config.host, 'cdn.contentstack.io'); // rest-preview.contentstack.com - assert.end(); -}); + expect(livePreviewObject.enable).toBe(false); + expect(stack.config.host).toBe('cdn.contentstack.io'); // rest-preview.contentstack.com + }); -test('should check host when live preview is enabled and management token is provided', function(assert) { - const stack = Contentstack.Stack({ - 'api_key': process.env.API_KEY, - 'delivery_token': process.env.DELIVERY_TOKEN, - 'environment': process.env.ENVIRONMENT, - live_preview: { - enable: true, - management_token: 'management_token' - } - }); + test('should check host when live preview is enabled and management token is provided', () => { + init.stack.live_preview = init.stack.live_preview || {}; + init.stack.live_preview.enable = true; + init.stack.live_preview.management_token = 'management_token'; + const stack = Contentstack.Stack(init.stack); + const livePreviewObject = stack.config.live_preview; - assert.notEqual(livePreviewObject, 'undefined'); - assert.notEqual(livePreviewObject.enable, 'undefined'); - assert.notEqual(livePreviewObject.host, 'undefined'); - assert.equal(stack.config.host, 'cdn.contentstack.io'); // rest-preview.contentstack.com - assert.end(); -}); + expect(livePreviewObject).not.toBe('undefined'); + expect(livePreviewObject.enable).not.toBe('undefined'); + expect(livePreviewObject.host).not.toBe('undefined'); + expect(stack.config.host).toBe('cdn.contentstack.io'); // rest-preview.contentstack.com + }); -test('should check host when live preview is disabled and management token is provided', function(assert) { - const stack = Contentstack.Stack({ - 'api_key': process.env.API_KEY, - 'delivery_token': process.env.DELIVERY_TOKEN, - 'environment': process.env.ENVIRONMENT, - live_preview: { - enable: false, - management_token: 'management_token' - } - }); + test('should check host when live preview is disabled and management token is provided', () => { + init.stack.live_preview.enable = false; + init.stack.live_preview.management_token = 'management_token'; + const stack = Contentstack.Stack(init.stack); + const livePreviewObject = stack.config.live_preview; - assert.notEqual(livePreviewObject, 'undefined'); - assert.equal(livePreviewObject.enable, false); - assert.notEqual(livePreviewObject.host, 'undefined'); - assert.end(); -}); + expect(livePreviewObject).not.toBe('undefined'); + expect(livePreviewObject.enable).toBe(false); + expect(livePreviewObject.host).not.toBe('undefined'); + }); -test('should check host when live preview is enabled and preview token is provided', function(assert) { - const stack = Contentstack.Stack({ - 'api_key': process.env.API_KEY, - 'delivery_token': process.env.DELIVERY_TOKEN, - 'environment': process.env.ENVIRONMENT, - live_preview: { - enable: true, - preview_token: 'preview_token' - } - }); + test('should check host when live preview is enabled and preview token is provided', () => { + init.stack.live_preview.enable = true; + init.stack.live_preview.preview_token = 'preview_token'; + const stack = Contentstack.Stack(init.stack); + const livePreviewObject = stack.config.live_preview; - assert.notEqual(livePreviewObject, 'undefined'); - assert.notEqual(livePreviewObject.enable, 'undefined'); - assert.notEqual(livePreviewObject.host, 'undefined'); - assert.notEqual(livePreviewObject.preview_token, 'undefined'); - assert.equal(stack.config.host, 'cdn.contentstack.io'); - assert.end(); -}); + expect(livePreviewObject).not.toBe('undefined'); + expect(livePreviewObject.enable).not.toBe('undefined'); + expect(livePreviewObject.host).not.toBe('undefined'); + expect(livePreviewObject.preview_token).not.toBe('undefined'); + expect(stack.config.host).toBe('cdn.contentstack.io'); + }); -test('should check host when live preview is disabled and preview token is provided', function(assert) { - const stack = Contentstack.Stack({ - 'api_key': process.env.API_KEY, - 'delivery_token': process.env.DELIVERY_TOKEN, - 'environment': process.env.ENVIRONMENT, - live_preview: { - enable: false, - preview_token: 'preview_token' - } - }); + test('should check host when live preview is disabled and preview token is provided', () => { + init.stack.live_preview.enable = false; + init.stack.live_preview.preview_token = 'preview_token'; + const stack = Contentstack.Stack(init.stack); + const livePreviewObject = stack.config.live_preview; - assert.notEqual(livePreviewObject, 'undefined'); - assert.notEqual(livePreviewObject.enable, 'undefined'); - assert.notEqual(livePreviewObject.host, 'undefined'); - assert.notEqual(livePreviewObject.preview_token, 'undefined'); - assert.equal(stack.config.host, 'cdn.contentstack.io'); - assert.end(); -}); - + expect(livePreviewObject).not.toBe('undefined'); + expect(livePreviewObject.enable).not.toBe('undefined'); + expect(livePreviewObject.host).not.toBe('undefined'); + expect(livePreviewObject.preview_token).not.toBe('undefined'); + expect(stack.config.host).toBe('cdn.contentstack.io'); + }); +}); \ No newline at end of file diff --git a/test/sync/sync-testcases.js b/test/sync/sync-testcases.js index 70480e68..3655e5cd 100755 --- a/test/sync/sync-testcases.js +++ b/test/sync/sync-testcases.js @@ -1,108 +1,108 @@ -'use strict'; +"use strict"; /* * Module Dependencies. */ -const sync_testcase = require('tape'); -const Contentstack = require('../../dist/node/contentstack.js'); -const init = require('../sync_config.js'); +const Contentstack = require("../../dist/node/contentstack.js"); +const init = require("../config.js"); + let Stack; let sync_token = ""; -var total_count = 123; var pagination_token = ""; - -/* - * Initalise the Contentstack Instance - * */ -sync_testcase('Initalise the Contentstack Stack Instance', function(TC) { - setTimeout(function() { - Stack = Contentstack.Stack(init.stack); - Stack.setHost(init.host); - TC.end(); - }, 1000); -}); - -sync_testcase('default .Init()', function(assert) { - Stack - .sync({"init" : true}) - .then(function success(data) { - assert.equal(data.total_count, total_count, "Present Data and Totalcount is equal"); - assert.end(); - }); -}); - -sync_testcase('default .startdate()', function(assert) { - var date_entry_count = 7 - Stack - .sync({"init": true, "start_from": "2018-10-22"}) - .then(function success(data) { - assert.equal(data.total_count, date_entry_count, "Present data and filtered data count on date bases is equal"); - assert.end(); - }); -}); - - -sync_testcase('default .locale()', function(assert) { - var locale_entry_count = 123; - Stack - .sync({"init": "true", "locale": "en-us"}) - .then(function success(data) { - assert.equal(data.total_count, locale_entry_count, "Present data and filtered data count on locale bases is equal"); - assert.end(); - }); -}); - -sync_testcase('default .localeDate()', function(assert) { - var locale_date_entry_count = 7; - Stack - .sync({"init": true, "locale": "en-us", "start_from": "2018-10-22"}) - .then(function success(data) { - assert.equal(data.total_count, locale_date_entry_count, "Present data and filtered data count on date and locale bases is equal"); - assert.end(); - }); -}); - - -sync_testcase('default .pagination_token()', function(assert) { - - Stack - .sync({"pagination_token" : pagination_token}) - .then(function success(result) { - let pagination_count = result.items.length - assert.equal(pagination_count, 23, "pagination_token testcase executed successfully"); - assert.end(); - }); -}); - - -sync_testcase('default .contentTypeUid()', function(assert) { - Stack - .sync({"init": true, "content_type_uid": "session"}) - .then(function success(data) { - assert.equal(data.total_count, 31, "Present data and filtered data total count on contentType bases is equal"); - assert.end(); - }); -}); - -sync_testcase('default .type()', function(assert) { - var items_count = 8; - Stack - .sync({"init": true, "type": "asset_published"}) - .then(function success(data) { - assert.equal(data.total_count, items_count, "Present data and filtered data total count on type bases is equal"); - assert.end(); - }); -}); - -sync_testcase('default .sync_token()', function(assert) { - var sync_expected_count = 7 - - Stack - .sync({"sync_token" : sync_token}) - .then(function success(result) { - assert.equal(result.total_count, sync_expected_count, "Synced Data and Sync_total_count is equal"); - assert.end(); - }); +describe("ContentStack SDK Sync Tests", () => { + // Initialize the Contentstack Stack Instance + beforeAll(() => { + return new Promise((resolve) => { + // Initialize Stack with proper configuration + Stack = Contentstack.Stack(init.stack) + Stack.setHost(init.host); + setTimeout(resolve, 1000); + }); + }); + + describe("default .Init()", () => { + test("should initialize sync with correct total count", async () => { + const data = await Stack.sync({ init: true }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .startdate()", () => { + test("should filter entries by start date", async () => { + const data = await Stack.sync({ + init: "true", + start_from: "2018-10-22T00:00:00.000Z" + }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .locale()", () => { + test("should filter entries by locale", async () => { + const data = await Stack.sync({ + init: "true", + locale: "en-us" + }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .localeDate()", () => { + test("should filter entries by locale and date", async () => { + const data = await Stack.sync({ + init: "true", + locale: "en-us", + start_from: "2018-10-22T00:00:00.000Z" + }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .pagination_token()", () => { + test("should handle pagination correctly", async () => { + // This works only when it contains more than 100 records else sync token will be generated + + const initialData = await Stack.sync({ init: "true" }); + pagination_token = initialData.pagination_token; + expect(pagination_token).toBeUndefined(); + try { + await Stack.sync({ pagination_token }); + } catch (error) { + expect(error.message).toBe(`Invalid parameter value for key "pagination_token": must be a string, number, object, boolean, or RegExp.`); + } + }); + }); + + describe("default .contentTypeUid()", () => { + test("should filter entries by content type", async () => { + const data = await Stack.sync({ + init: "true", + content_type_uid: "source" + }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .type()", () => { + test("should filter entries by type", async () => { + const data = await Stack.sync({ + init: "true", + type: "asset_published" + }); + expect(data.total_count).toBeDefined(); + }); + }); + + describe("default .sync_token()", () => { + test("should handle sync token correctly", async () => { + // First get a valid sync token + const initialData = await Stack.sync({ init: "true" }); + sync_token = initialData.sync_token; + + const result = await Stack.sync({ sync_token }); + expect(result.total_count).toBeDefined(); + }); + }); }); diff --git a/test/typescript/stack.test.ts b/test/typescript/stack.test.ts index 1e54e703..50c00bfe 100644 --- a/test/typescript/stack.test.ts +++ b/test/typescript/stack.test.ts @@ -196,6 +196,34 @@ describe('Stack tests', () => { done(); }); + test('Stack initialization with Contentstack Config with fetchOptions, GCP-EU region test', done => { + const config : Contentstack.Config = { + api_key: 'api_key', + delivery_token: 'delivery_token', + environment: 'environment', + region: Contentstack.Region.GCP_EU, + fetchOptions:{ + timeout: 2000, + retryLimit: 4, + retryDelay: 40, + logHandler: () => { + + } + } + }; + const stack = Contentstack.Stack(config); + + expect(stack.cachePolicy).toEqual(Contentstack.CachePolicy.IGNORE_CACHE); + expect(stack.environment).toEqual('environment'); + expect(stack.config.host).toEqual('gcp-eu-cdn.contentstack.com'); + expect(stack.config.port).toEqual(443); + expect(stack.config.version).toEqual("v3"); + expect(stack.fetchOptions.timeout).toEqual(2000); + expect(stack.fetchOptions.retryLimit).toEqual(4); + expect(stack.fetchOptions.retryDelay).toEqual(40); + done(); + }); + test('Stack initialization with region EU test', done => { const stack = Contentstack.Stack('api_key', 'delivery_token', 'environment', Contentstack.Region.AZURE_NA); expect(stack.cachePolicy).toEqual(Contentstack.CachePolicy.IGNORE_CACHE); diff --git a/test/typescript/sync.test.ts b/test/typescript/sync.test.ts new file mode 100644 index 00000000..e6614573 --- /dev/null +++ b/test/typescript/sync.test.ts @@ -0,0 +1,37 @@ +import * as Contentstack from '../..'; + +const stack = Contentstack.Stack({ api_key: 'api_key', delivery_token: 'delivery_token', environment: 'environment', fetchOptions: { + logHandler: () => { + + } +}}); + +describe('Sync Test', () => { + test('Sync init test', done => { + const response = makeSync({"init": true}) + expect(response).not.toEqual(undefined) + done(); + }); + + test('Sync with startdate test', done => { + const response = makeSync({"init": true, "start_from": "2025-04-02"}) + expect(response).not.toEqual(undefined) + done(); + }); + + test('Sync with locale test', done => { + const response = makeSync({"init": true, "locale": "en-us"}) + expect(response).not.toEqual(undefined) + done(); + }); + + test('Sync with contentTypeUid test', done => { + const response = makeSync({"init": true, "content_type_uid": "ct_uid"}) + expect(response).not.toEqual(undefined) + done(); + }); +}); + +function makeSync(params: any) { + return stack.sync(params) +} \ No newline at end of file