diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index bcbc7fecd..000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,192 +0,0 @@ -version: 2.1 - -executors: - python-executor: - working_directory: ~/phovea-python - docker: - - image: circleci/python:3.10-buster - node-executor: - working_directory: ~/phovea-web - docker: - - image: circleci/node:14.17-buster - -jobs: - python-build: - executor: python-executor - steps: - - checkout - - restore_cache: - key: deps-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_dev.txt" }} - - run: - name: Install pip requirements - command: | - virtualenv ~/venv - . ~/venv/bin/activate - make develop - - save_cache: - key: deps-{{ .Branch }}-{{ checksum "requirements.txt" }}-{{ checksum "requirements_dev.txt" }} - paths: - - ~/venv - - run: - name: Force an update of pip dependencies from git repositories # not sure if this is working ? - command: | - . ~/venv/bin/activate - pip install --upgrade --upgrade-strategy=only-if-needed -e .[develop] - - run: - name: Show installed pip packages - command: | - . ~/venv/bin/activate - pip list || true - - run: - name: Linting - command: | - . ~/venv/bin/activate - make lint check-format - - run: - name: Run tests - command: | - . ~/venv/bin/activate - make test - - run: - name: Build wheel - command: | - . ~/venv/bin/activate - make build - - store_artifacts: - path: dist_python - destination: dist-python - - persist_to_workspace: - root: ~/. - paths: phovea-python - python-publish: - executor: python-executor - steps: - - attach_workspace: - at: ~/. - - run: ls -a - - run: - name: Install twine - command: | - virtualenv ~/venv - . ~/venv/bin/activate - pip install twine - - run: - name: Authentication - command: | - echo -e "[pypi]" >> ~/.pypirc - echo -e "repository = $PYPI_REPOSITORY" >> ~/.pypirc - echo -e "username = $PYPI_USERNAME" >> ~/.pypirc - echo -e "password = $PYPI_PASSWORD" >> ~/.pypirc - - run: - name: Publish package - command: | - . ~/venv/bin/activate - twine upload dist_python/* - web-build: - executor: node-executor - steps: - - checkout - - run: - name: Show Node.js and npm version - command: | - node -v - npm -v - - restore_cache: - key: deps2-{{ .Branch }}-{{ checksum "package.json" }} - - run: - name: Install npm dependencies - command: npm install - - run: - name: Remove npm dependencies installed from git repositories (avoid caching of old commits) - command: | - (grep -l '._resolved.: .\(git[^:]*\|bitbucket\):' ./node_modules/*/package.json || true) | xargs -r dirname | xargs -r rm -rf - - save_cache: - key: deps2-{{ .Branch }}-{{ checksum "package.json" }} - paths: ./node_modules - - run: - name: Install npm dependencies from git repositories (always get latest commit) - command: npm install - - run: - name: Show installed npm dependencies - command: npm list --depth=1 || true - - run: - name: Build - command: npm run dist - - store_artifacts: - path: dist - destination: dist-web - - persist_to_workspace: - root: ~/. - paths: phovea-web - web-publish: - executor: node-executor - steps: - - attach_workspace: - at: ~/. - - run: ls -a - - run: - name: Authentication - command: | - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - - run: - name: Publish package - command: npm publish -workflows: - version: 2.1 -# build-nightly: -# triggers: -# - schedule: -# cron: "15 1 * * 1-5" # "At 01:15 on every day-of-week from Monday through Friday.โ€, see: https://crontab.guru/#15_1_*_*_1-5 -# filters: -# branches: -# only: -# - develop -# jobs: -# - python-build -# - web-build - build-branches-only: - jobs: - - python-build: - filters: - tags: - ignore: /.*/ - - web-build: - filters: - tags: - ignore: /.*/ - build-publish-tag: - jobs: - - python-build: - filters: - branches: - ignore: /.*/ - tags: - only: /^v.*/ - - web-build: - filters: - branches: - ignore: /.*/ - tags: - only: /^v.*/ - - python-publish: - context: - - org-public - requires: - - python-build - - web-build - filters: - branches: - ignore: /.*/ - tags: - only: /^v.*/ - - web-publish: - context: - - org-public - requires: - - python-build - - web-build - filters: - branches: - ignore: /.*/ - tags: - only: /^v.*/ diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 5bb9027b5..ab517a75a 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,2 @@ * @datavisyn/core + diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md deleted file mode 100644 index bdb156f5c..000000000 --- a/.github/ISSUE_TEMPLATE.md +++ /dev/null @@ -1,17 +0,0 @@ -* Release number or git hash: -* Web browser version and OS: -* Environment (local or deployed): - -### Steps to reproduce - -1. -2. - -### Observed behavior -* Any unexpected output or action (or lack of expected output or action) -* Web browser console errors (including tracebacks) -* Server errors (relevant messages and tracebacks) -* Static or animated images showing the UI behavior - -### Expected behavior -* diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md new file mode 100644 index 000000000..d39e18b76 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -0,0 +1,36 @@ +--- +name: ๐Ÿ›Bug Report +about: Create a bug report to help us improve +title: "" +labels: ["type: bug"] +assignees: "" + +--- + +### Environment + + * Release number or git hash: + * Browser: + * Deployed / Local: +--- + +### Steps to reproduce the bug + +1. Open a list of ... / Search ... +2. Do something else + +### Observed Behavior + +> Please provide a short description of the actual behavior you observed +> If applicable, add screenshots to help explain your problem. +> - Any unexpected output or action (or lack of expected output or action) +> - Web browser console errors (including tracebacks) +> - Server errors (relevant messages and tracebacks) +> - Static or animated images showing the UI behavior + +### Expected Behavior + +> Please provide a short description which behavior you expected from your steps + +Thanks for taking the time to fill out this bug report ๐Ÿค— +Make sure there aren't any open/closed issues for this topic ๐Ÿ˜ƒ diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 000000000..1be6f2c11 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,17 @@ +--- +name: โœจFeature Request +about: Request a new feature or enhancement +title: "" +labels: ["type: feature"] +--- + +## Short description + +Please provide a short description which summarizes the idea behind this feature request and why this is useful. + +## User stories + +* As a *user*, I want to ... so that ... + + +Please make sure this feature request hasn't been already submitted by someone by looking through other open/closed issues ๐Ÿ˜ƒ diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..266c6ef00 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,45 @@ +Closes *list issues numbers here* + +### Developer Checklist (Definition of Done) + +**Issue** + +- [ ] All acceptance criteria from the issue are met +- [ ] Tested in latest Chrome/Firefox + +**UI/UX/Vis** + +- [ ] Requires UI/UX/Vis review + - [ ] Reviewer(s) are notified (_tag assignees_) + - [ ] Review has occurred (_link to notes_) + - [ ] Feedback is included in this PR + - [ ] Reviewer(s) approve of concept and design + +**Code** + +- [ ] Branch is up-to-date with the branch to be merged with, i.e., develop +- [ ] Code is cleaned up and formatted +- [ ] Unit tests are written (frontend/backend if applicable) +- [ ] Integration tests are written (if applicable) + +**PR** + +- [ ] Descriptive title for this pull request is provided (will be used for release notes later) +- [ ] Reviewer and assignees are defined +- [ ] Add type label (e.g., *bug*, *feature*) to this pull request +- [ ] Add release label (e.g., `release: minor`) to this PR following [semver](https://semver.org/) +- [ ] The PR is connected to the corresponding issue (via `Closes #...`) +- [ ] [Summary of changes](#summary-of-changes) is written + + +### Summary of changes + +- + +### Screenshots + + +### Additional notes for the reviewer(s) + +- +Thanks for creating this pull request ๐Ÿค— diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 000000000..ddec72886 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,8 @@ +name: build + +on: [push, workflow_dispatch] + +jobs: + build: + uses: datavisyn/github-workflows/.github/workflows/build-node-python.yml@main + secrets: inherit diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml new file mode 100644 index 000000000..843d1f292 --- /dev/null +++ b/.github/workflows/publish.yml @@ -0,0 +1,8 @@ +name: publish + +on: workflow_dispatch + +jobs: + publish: + uses: datavisyn/github-workflows/.github/workflows/publish-node-python.yml@main + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..1720aaba4 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,8 @@ +name: release + +on: workflow_dispatch + +jobs: + release: + uses: datavisyn/github-workflows/.github/workflows/release-source.yml@main + secrets: inherit diff --git a/dist/components/buildInfo.d.ts.map b/dist/components/buildInfo.d.ts.map index 37f88473a..05ca62fce 100644 --- a/dist/components/buildInfo.d.ts.map +++ b/dist/components/buildInfo.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"buildInfo.d.ts","sourceRoot":"","sources":["../../src/components/buildInfo.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAiB,SAAQ,UAAU;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,UAAU,gBAAiB,SAAQ,UAAU;IAC3C,YAAY,EAAE,GAAG,CAAC;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB;AAED,qBAAa,SAAS;IACR,OAAO,CAAC,MAAM;IAAoB,OAAO,CAAC,MAAM,CAAC;gBAAzC,MAAM,EAAE,gBAAgB,EAAU,MAAM,CAAC,EAAE,gBAAgB;IAE/E,QAAQ;IAIR,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,kBAAkB;IAkB1B,MAAM;IASN,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC;CAOnC"} \ No newline at end of file +{"version":3,"file":"buildInfo.d.ts","sourceRoot":"","sources":["../../src/components/buildInfo.ts"],"names":[],"mappings":"AAGA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,gBAAiB,SAAQ,UAAU;IAC3C,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,OAAO,EAAE,UAAU,EAAE,CAAC;CACvB;AAED,UAAU,gBAAiB,SAAQ,UAAU;IAC3C,YAAY,EAAE,GAAG,CAAC;IAClB,iBAAiB,EAAE,GAAG,CAAC;CACxB;AAED,qBAAa,SAAS;IACR,OAAO,CAAC,MAAM;IAAoB,OAAO,CAAC,MAAM,CAAC;gBAAzC,MAAM,EAAE,gBAAgB,EAAU,MAAM,CAAC,EAAE,gBAAgB;IAE/E,QAAQ;IAIR,OAAO,CAAC,cAAc;IAatB,OAAO,CAAC,kBAAkB;IAkB1B,MAAM;IASN,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC;CAcnC"} \ No newline at end of file diff --git a/dist/components/buildInfo.js b/dist/components/buildInfo.js index 093902611..cb29db404 100644 --- a/dist/components/buildInfo.js +++ b/dist/components/buildInfo.js @@ -46,7 +46,14 @@ export class BuildInfo { static build() { const buildInfos = Promise.all([ window.fetch('./buildInfo.json').then((response) => response.json()), - AppContext.getInstance().offline ? null : AppContext.getInstance().getAPIJSON('/buildInfo.json'), + AppContext.getInstance().offline + ? null + : AppContext.getInstance() + .getAPIJSON('/buildInfo.json') + .catch((e) => { + console.error('Error fetching /api/buildInfo.json', e); + return null; + }), ]); return buildInfos.then((args) => new BuildInfo(args[0], args[1])); } diff --git a/dist/components/buildInfo.js.map b/dist/components/buildInfo.js.map index 3139161ac..33b51a6ff 100644 --- a/dist/components/buildInfo.js.map +++ b/dist/components/buildInfo.js.map @@ -1 +1 @@ -{"version":3,"file":"buildInfo.js","sourceRoot":"","sources":["../../src/components/buildInfo.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"buildInfo.js","sourceRoot":"","sources":["../../src/components/buildInfo.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.d.ts b/dist/index.d.ts index f5b9fd0bd..0516dd900 100644 --- a/dist/index.d.ts +++ b/dist/index.d.ts @@ -10,6 +10,7 @@ export * from './hooks'; export * from './i18n'; export * from './idtype'; export * from './import'; +export * from './initialize'; export * from './layout'; export * from './lineup'; export * from './public'; diff --git a/dist/index.d.ts.map b/dist/index.d.ts.map index c36cc7293..29b9d86b3 100644 --- a/dist/index.d.ts.map +++ b/dist/index.d.ts.map @@ -1 +1 @@ -{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"} \ No newline at end of file +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/index.js b/dist/index.js index 3830e57ae..495a3fc77 100644 --- a/dist/index.js +++ b/dist/index.js @@ -10,6 +10,7 @@ export * from './hooks'; export * from './i18n'; export * from './idtype'; export * from './import'; +export * from './initialize'; export * from './layout'; export * from './lineup'; export * from './public'; diff --git a/dist/index.js.map b/dist/index.js.map index 8aab4ec55..ef550a2da 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"} \ No newline at end of file +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,mBAAmB,CAAC;AAClC,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,UAAU,CAAC;AACzB,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,OAAO,CAAC;AACtB,cAAc,WAAW,CAAC"} \ No newline at end of file diff --git a/dist/scss/components/_namedsetlist.scss b/dist/scss/components/_namedsetlist.scss index de93caa17..f397af80f 100644 --- a/dist/scss/components/_namedsetlist.scss +++ b/dist/scss/components/_namedsetlist.scss @@ -7,7 +7,7 @@ .custom-named-sets header::before, .other-named-sets header::before { @extend .fas; - width: (18em / 14); + width: calc(18em / 14); text-align: center; } diff --git a/dist/scss/components/_view_lineup.scss b/dist/scss/components/_view_lineup.scss index de6f8ee8a..77606774e 100644 --- a/dist/scss/components/_view_lineup.scss +++ b/dist/scss/components/_view_lineup.scss @@ -59,7 +59,7 @@ .lineup-engine { position: absolute; top: 0; - right: 0; + right: 4px; // leave some space for the LineUp selection indicator next to the scroll bar bottom: 0; left: 0; overflow: auto; diff --git a/package.json b/package.json index c07cfb820..a83d8922b 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "tdp_core", "description": "Target discovery platform for exploring rankings of genes, disease models, and other entities.", - "version": "15.0.1", + "version": "15.1.0", "author": { "name": "datavisyn GmbH", "email": "contact@datavisyn.io", diff --git a/src/components/buildInfo.ts b/src/components/buildInfo.ts index faccc17a7..5cda22d0a 100644 --- a/src/components/buildInfo.ts +++ b/src/components/buildInfo.ts @@ -67,7 +67,14 @@ export class BuildInfo { static build(): Promise { const buildInfos = Promise.all([ (window).fetch('./buildInfo.json').then((response) => response.json()), - AppContext.getInstance().offline ? null : AppContext.getInstance().getAPIJSON('/buildInfo.json'), + AppContext.getInstance().offline + ? null + : AppContext.getInstance() + .getAPIJSON('/buildInfo.json') + .catch((e) => { + console.error('Error fetching /api/buildInfo.json', e); + return null; + }), ]); return buildInfos.then((args: any[]) => new BuildInfo(args[0], args[1])); } diff --git a/src/index.ts b/src/index.ts index b2299a0d2..851a81259 100644 --- a/src/index.ts +++ b/src/index.ts @@ -10,6 +10,7 @@ export * from './hooks'; export * from './i18n'; export * from './idtype'; export * from './import'; +export * from './initialize'; export * from './layout'; export * from './lineup'; export * from './public'; diff --git a/src/scss/components/_namedsetlist.scss b/src/scss/components/_namedsetlist.scss index de93caa17..f397af80f 100644 --- a/src/scss/components/_namedsetlist.scss +++ b/src/scss/components/_namedsetlist.scss @@ -7,7 +7,7 @@ .custom-named-sets header::before, .other-named-sets header::before { @extend .fas; - width: (18em / 14); + width: calc(18em / 14); text-align: center; } diff --git a/src/scss/components/_view_lineup.scss b/src/scss/components/_view_lineup.scss index de6f8ee8a..77606774e 100644 --- a/src/scss/components/_view_lineup.scss +++ b/src/scss/components/_view_lineup.scss @@ -59,7 +59,7 @@ .lineup-engine { position: absolute; top: 0; - right: 0; + right: 4px; // leave some space for the LineUp selection indicator next to the scroll bar bottom: 0; left: 0; overflow: auto; diff --git a/tdp_core/security/store/alb_security_store.py b/tdp_core/security/store/alb_security_store.py index 417a89312..449ee0718 100644 --- a/tdp_core/security/store/alb_security_store.py +++ b/tdp_core/security/store/alb_security_store.py @@ -4,7 +4,7 @@ import jwt from ... import manager -from ..model import User +from ..model import LogoutReturnValue, User from .base_store import BaseStore _log = logging.getLogger(__name__) @@ -41,7 +41,7 @@ def logout(self, user): if self.signout_url: payload["alb_security_store"] = {"redirect": self.signout_url} - return {"data": payload, "cookies": cookies} + return LogoutReturnValue(data=payload, cookies=cookies) def create(): diff --git a/tdp_core/server/visyn_server.py b/tdp_core/server/visyn_server.py index fb4c122b6..281adfb5e 100644 --- a/tdp_core/server/visyn_server.py +++ b/tdp_core/server/visyn_server.py @@ -143,6 +143,6 @@ def create_visyn_server( # TODO: Move up? app.add_api_route("/health", health) - app.add_api_route("/buildInfo.json", build_info) + app.add_api_route("/api/buildInfo.json", build_info) return app diff --git a/tdp_core/tests/test_main_app.py b/tdp_core/tests/test_main_app.py index 58744212c..830e8a07f 100644 --- a/tdp_core/tests/test_main_app.py +++ b/tdp_core/tests/test_main_app.py @@ -4,6 +4,18 @@ def test_health(client): assert response.json() == "ok" +def test_buildinfo_json(client): + response = client.get("/api/buildInfo.json") + assert response.status_code == 200 + build_info = response.json() + # Check for the main build name + assert build_info["name"] == "tdp_core" + # Check if plugins are returned as list + assert isinstance(build_info["plugins"], list) + # Check if dependencies are returned (i.e. look for FastAPI) + assert next(d for d in build_info["dependencies"] if d.lower().startswith("fastapi")) + + def test_idtype(client): response = client.get("/api/idtype/") assert response.status_code == 200 diff --git a/tdp_core/tests/test_security_login.py b/tdp_core/tests/test_security_login.py index 5b6a622ea..147af45fc 100644 --- a/tdp_core/tests/test_security_login.py +++ b/tdp_core/tests/test_security_login.py @@ -4,6 +4,7 @@ from tdp_core import manager from tdp_core.security.model import User +from tdp_core.security.store.alb_security_store import create as create_alb_security_store def test_api_key(client: TestClient): @@ -110,3 +111,33 @@ def test_jwt_token_location(client: TestClient): # Does work even without header response = client.get("/loggedinas") assert response.json() != '"not_yet_logged_in"' + + +def test_alb_security_store(client: TestClient): + # Add some basic configuration + manager.settings.tdp_core.security.store.alb_security_store.enable = True + manager.settings.tdp_core.security.store.alb_security_store.cookie_name = "TestCookie" + manager.settings.tdp_core.security.store.alb_security_store.signout_url = "http://localhost/logout" + + store = create_alb_security_store() + assert store is not None + + manager.security.user_stores = [store] + + # Header created with a random token containing "email" + headers = { + "X-Amzn-Oidc-Identity": "", + "X-Amzn-Oidc-Accesstoken": "", + "X-Amzn-Oidc-Data": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJlbWFpbCI6ImFkbWluQGxvY2FsaG9zdCIsInN1YiI6ImFkbWluIiwicm9sZXMiOlsiYWRtaW4iXSwiZXhwIjoxNjU3MTg4MTM4LjQ5NDU4Nn0.-Ye9j9z37gJdoKgrbeYbI8buSw_c6bLBShXt4XxwQHI", + } + + # Check loggedinas with a JWT + response = client.get("/loggedinas", headers=headers) + assert response.status_code == 200 + assert response.json() != '"not_yet_logged_in"' + assert response.json()["name"] == "admin@localhost" + + # Logout and check if we get the correct redirect url + response = client.post("/logout", headers=headers) + assert response.status_code == 200 + assert response.json()["alb_security_store"]["redirect"] == "http://localhost/logout"