Compare commits

..

78 Commits

Author SHA1 Message Date
Dark-Alex-17 0048d71b74 feat: Support alternative keymappings for all keys, featuring hjkl movements 2025-03-17 22:02:15 -06:00
Dark-Alex-17 c633347ecc Merge remote-tracking branch 'refs/remotes/origin/develop' 2025-03-17 20:49:52 -06:00
Alex Clarke ecd6a0ec32 Merge pull request #37 from Dark-Alex-17/custom-themes
Support Themes
2025-03-17 14:23:18 -06:00
Dark-Alex-17 30507d9d01 docs: Updated the README to include the new flags 2025-03-17 13:26:46 -06:00
Dark-Alex-17 6245a794d5 docs: Update all screenshots to not have any auto-generated usernames in the tags columns 2025-03-10 16:22:24 -06:00
Dark-Alex-17 5c822e4890 Merge branch 'develop' 2025-03-10 16:13:48 -06:00
Dark-Alex-17 cab06fe43f fix: Marked the Season.statistics field as Option so that a panic does not happen for outdated Sonarr data. This resolves #35 2025-03-10 16:13:04 -06:00
Dark-Alex-17 b4ff5f3351 feat: Added the Eldritch theme and updated documentation 2025-03-10 15:49:40 -06:00
Dark-Alex-17 0834802481 fix: When adding a film from the Collection Details modal, the render order was wrong: Radarr Library -> Collection Table -> Add Movie Prompt (missing the Collection details prompt too). Correct order is: Collection Table -> Collection Details Modal -> Add Movie Modal 2025-03-10 15:08:02 -06:00
Dark-Alex-17 3afd74dcbf fix: Fixed a bug that was rendering encompassing blocks after other widgets were rendered, thus overwriting the custom styles on each previously rendered widget 2025-03-10 15:01:58 -06:00
Dark-Alex-17 b1a0bdfbb6 Merge branch 'develop' 2025-03-07 12:02:47 -07:00
Dark-Alex-17 6d38bc5e1d Merge branch 'main' 2025-03-07 12:02:19 -07:00
Dark-Alex-17 5ba1ba15c9 ci: Update to the most recent Rust version 2025-03-07 11:55:32 -07:00
Dark-Alex-17 db05d2abfb Merge branch 'develop' into custom-themes 2025-03-07 10:37:48 -07:00
Dark-Alex-17 1840c4e39a Merge branch 'main' into develop
# Conflicts:
#	proc_macros/enum_display_style_derive/src/lib.rs
2025-03-07 10:37:23 -07:00
Dark-Alex-17 c5a3f424d6 refactor: Reformatted code to make the format checks pass 2025-03-07 10:36:40 -07:00
Dark-Alex-17 04aa6b81b5 Merge branch 'develop' into custom-themes 2025-03-07 10:35:07 -07:00
Dark-Alex-17 5ff3b9b996 Merge branch 'main' into develop 2025-03-07 10:34:16 -07:00
Dark-Alex-17 228e4a61a4 fix: Updated ring dependency to mitigate CWE-770 2025-03-07 10:33:57 -07:00
Dark-Alex-17 df38ea5413 feat: Write built in themes to the themes file on first run so users can define custom themes 2025-03-06 17:44:52 -07:00
Dark-Alex-17 709f6ca6ca test: Added integration tests for the ValidateTheme macro 2025-03-06 16:00:50 -07:00
Dark-Alex-17 b012fc29e4 Merge branch 'develop' into custom-themes
# Conflicts:
#	Cargo.toml
2025-03-06 15:35:05 -07:00
Dark-Alex-17 bdad723aef refactor: Formatted files using rustfmt 2025-03-06 15:32:59 -07:00
Dark-Alex-17 f97d46cec3 refactor: Created a derive macro for defining the display style of Enum models and removed the use of the EnumDisplayStyle trait 2025-03-06 15:29:30 -07:00
Dark-Alex-17 7381eaef57 refactor: Expanded the serde_enum_from macro to further reduce code duplication 2025-03-05 15:09:51 -07:00
Dark-Alex-17 72c922b311 feat: Created a theme validation macro to verify theme configurations before allowing the TUI to start 2025-03-05 14:37:34 -07:00
Alex Clarke fd14a8152c fix: change the name of the theme configuration file to 'themes' 2025-03-04 18:29:21 -07:00
Dark-Alex-17 5cb60c317d feat: Initial support for custom user-defined themes 2025-03-04 18:09:09 -07:00
Dark-Alex-17 847de75713 fix: Modified the Sonarr DownloadRecord so that the episode_id is optional to prevent crashes for weird downloads 2025-03-01 14:50:20 -07:00
Dark-Alex-17 58723cf3e8 ci: Ensure the docker release is fully up-to-date 2025-02-28 21:45:05 -07:00
Dark-Alex-17 c613168bfb docs: Updated the CHANGELOG accordingly 2025-02-28 21:26:13 -07:00
github-actions[bot] 6f83de77f2 chore: Bump the version in Cargo.lock 2025-03-01 03:30:05 +00:00
github-actions[bot] 3f6ef3beb4 bump: version 0.5.0 → 0.5.1 [skip ci] 2025-03-01 03:30:04 +00:00
Dark-Alex-17 14e50c1465 Merge remote-tracking branch 'refs/remotes/origin/main' 2025-02-28 20:29:29 -07:00
Dark-Alex-17 0aa9fdca14 ci: Overwrite previous artifact uploads for proper releases 2025-02-28 20:29:15 -07:00
github-actions[bot] dc50820abc chore: Bump the version in Cargo.lock 2025-03-01 03:08:01 +00:00
github-actions[bot] 81afce78ad bump: version 0.4.2 → 0.5.0 [skip ci] 2025-03-01 03:07:57 +00:00
Dark-Alex-17 8a0b912601 ci: Updated the release flow to use the newer upload/download artifact actions 2025-02-28 20:06:41 -07:00
Dark-Alex-17 85105a953e docs: Pre-Release update of versions and added link to the Matrix Space. 2025-02-28 16:45:16 -07:00
Dark-Alex-17 40f3452d08 ci: Removed the minimal-versions check 2025-02-27 20:51:50 -07:00
Dark-Alex-17 a287a5c903 docs: Updated the README to also include details on the new CLI flags 2025-02-27 20:51:00 -07:00
Dark-Alex-17 f30e5270d8 refactor: Updated dependencies 2025-02-27 20:45:32 -07:00
Dark-Alex-17 104bcd7bb2 refactor: Addressed Cargo fmt complaints 2025-02-27 20:42:32 -07:00
Dark-Alex-17 fd6fcfc98f feat: CLI Support for multiple Servarr instances 2025-02-27 20:37:03 -07:00
Dark-Alex-17 f87e02cd7c test: Added in unit tests for TUI support for multiple custom named Servarrs 2025-02-27 19:30:17 -07:00
Dark-Alex-17 9b63b10118 feat: Support for multiple servarr definitions - no tests [skip ci] 2025-02-27 18:00:28 -07:00
Dark-Alex-17 111485e7c4 feat: Support for loading Servarr API tokens from a file 2025-02-27 16:53:29 -07:00
Alex Clarke 0167753cfe Merge pull request #30 from tangowithfoxtrot/var-interpolation
feat: environment variable interpolation in the managarr config file
2025-02-19 17:52:23 -07:00
Alex Clarke 73131cc518 Merge branch 'main' into var-interpolation 2025-02-19 17:40:16 -07:00
Dark-Alex-17 25576757bb ci: Updated codecov config to consider patches as well to hopefully fix PR issues [skip ci] 2025-02-19 17:40:03 -07:00
Dark-Alex-17 105c8f3a82 test: Hopefully the final environment variable name fix to correct all race conditions with parallel tests 2025-02-19 17:27:56 -07:00
Dark-Alex-17 5164d81492 test: Fix a potential race condition happening with parallel tests 2025-02-19 15:59:31 -07:00
Dark-Alex-17 319e5f1ac2 test: Added remaining unit tests for the deserialize_optional_env_var deserialization functions 2025-02-19 15:44:55 -07:00
Alex Clarke b24c2fbeb1 Merge branch 'main' into var-interpolation 2025-02-19 15:14:41 -07:00
Dark-Alex-17 bc5053c39c fix: Updated openssl to 0.10.70 to mitigate CVE-2025-24898 2025-02-03 16:06:47 -07:00
tangowithfoxtrot f06a031c93 Merge branch 'main' into var-interpolation 2025-01-26 14:40:14 -08:00
tangowithfoxtrot 8d450dea5a Merge branch 'main' into var-interpolation 2025-01-26 14:36:45 -08:00
Dark-Alex-17 c4ace8c53f feat: Tweaked the implementation for environment variables in the config a bit 2025-01-26 14:59:09 -07:00
Dark-Alex-17 78f104f558 refactor: Added a debug line for logging to output the config used when starting Managarr 2025-01-26 14:56:37 -07:00
Dark-Alex-17 e8a6f740b9 refactor: Updated the 2018 idiom lint to the 2021_compatibility lint 2025-01-26 14:47:40 -07:00
tangowithfoxtrot 6f3c6ec840 feat: var interpolation 2025-01-26 09:28:47 -08:00
Alex Clarke 47a3ef1d8b Merge pull request #29 from Dark-Alex-17/license-update
Updated license and attribution requirements
2025-01-21 15:47:00 -07:00
Alex Clarke 367e9bf33b Added attribution guidelines to the CONTRIBUTING
Added attribution guidelines to the CONTRIBUTING file so the license is easier to understand
2025-01-21 15:10:01 -07:00
Alex Clarke f122b02424 Do not require attributions for forks
Update the LICENSE to not require an attribution for forks that merge back into the main/aren't distributed as separate projects
2025-01-21 14:58:35 -07:00
Alex Clarke 3a09c17f0a Update LICENSE
Made the attribution wording more flexible and less legal in nature.
2025-01-21 14:53:30 -07:00
Alex Clarke 6773abb04e Update LICENSE due to scammer abuse
Updated the LICENSE to incorporate an attribution clause, and prohibit commercial use. 

This was done in response to a recently discovered abuse of some scammers using both my GitHub and this project in job applications to scam other companies and job applicants, offering to "adapt the project to the needs of their internal tools". 

Previously, this would have been fine. However, with scams spiking recently and myself struggling to find a job, this kind of abuse is, regrettably, something I must limit.
2025-01-21 13:14:15 -07:00
Dark-Alex-17 b757d66d7a fix: Addressed rustfmt complaints 2025-01-18 15:33:56 -07:00
Dark-Alex-17 81cb7a750c refactor: Removed unnecessary clones in the networking module to speed up network request handling 2025-01-18 15:23:03 -07:00
Dark-Alex-17 3be59108a9 refactor: Corrected some clone instead of copy behaviors in the command line handlers 2025-01-18 14:54:25 -07:00
Dark-Alex-17 fac9c45aee refactor: Removed unnecessary clone from stateful table 2025-01-18 14:24:23 -07:00
Dark-Alex-17 184bd2b510 refactor: Removed unnecessary clone call from extract_and_add_tag_ids_vec method 2025-01-18 14:15:52 -07:00
Dark-Alex-17 fda69178b9 refactor: Reduced the number of clones necessary when building modal structs 2025-01-18 13:56:18 -07:00
Dark-Alex-17 652bbcd5d4 refactor: Refactored a handful of Option calls to use take instead 2025-01-18 13:00:21 -07:00
Dark-Alex-17 fd35106df8 refactor: Renamed KeyEventHandler::with to KeyEventHandler::new to keep with Rust best practices and conventions 2025-01-18 12:43:25 -07:00
Alex Clarke 5ead5bc3d6 docs: removed the Unraid section of the README now that the issue has been corrected and fixed. 2024-12-31 16:55:39 -06:00
Dark-Alex-17 3ce0003315 docs: Added installation instructions for Nix and a note for Unraid users until the template is corrected by the maintainer 2024-12-30 11:25:15 -07:00
Alex Clarke ee94059a15 fix: Corrected typo in the managarr.nuspec.template 2024-12-21 21:26:38 -07:00
Dark-Alex-17 844742053d ci: Finalized corrected release workflow [skip ci] 2024-12-21 16:52:29 -07:00
214 changed files with 7585 additions and 4178 deletions
+4 -4
View File
@@ -76,15 +76,15 @@ jobs:
RUSTDOCFLAGS: --cfg docsrs RUSTDOCFLAGS: --cfg docsrs
msrv: msrv:
# check that we can build using the minimal rust version that is specified by this crate # check that we can build using the minimal rust version that is specified by this crate
name: 1.82.0 / check name: 1.85.0 / check
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Install 1.82.0 - name: Install 1.85.0
uses: dtolnay/rust-toolchain@master uses: dtolnay/rust-toolchain@master
with: with:
toolchain: 1.82.0 toolchain: 1.85.0
- name: cargo +1.82.0 check - name: cargo +1.85.0 check
run: cargo check run: cargo check
+173 -168
View File
@@ -98,9 +98,8 @@ jobs:
git push origin --follow-tags git push origin --follow-tags
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: artifacts
path: artifacts path: artifacts
build-release-artifacts: build-release-artifacts:
@@ -236,10 +235,11 @@ jobs:
cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.sha256 artifacts/ cp target/${{ matrix.job.target }}/release/${{ env.RELEASE_NAME }}.sha256 artifacts/
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: artifacts name: artifacts-${{ env.RELEASE_NAME }}
path: artifacts path: artifacts
overwrite: true
publish-github-release: publish-github-release:
name: publish-github-release name: publish-github-release
@@ -252,10 +252,10 @@ jobs:
fetch-depth: 0 fetch-depth: 0
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
with: with:
name: artifacts
path: artifacts path: artifacts
merge-multiple: true
- name: Ensure repository is up-to-date - name: Ensure repository is up-to-date
run: | run: |
@@ -306,195 +306,200 @@ jobs:
prerelease: false prerelease: false
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v4
with: with:
name: artifacts
path: artifacts path: artifacts
overwrite: true
# publish-chocolatey-package: publish-chocolatey-package:
# needs: [publish-github-release] needs: [publish-github-release]
# name: Publish Chocolatey Package name: Publish Chocolatey Package
# runs-on: windows-latest runs-on: windows-latest
# steps: steps:
# - name: Checkout repository - name: Checkout repository
# uses: actions/checkout@v4 uses: actions/checkout@v4
# with: with:
# fetch-depth: 1 fetch-depth: 1
# - name: Get release artifacts - name: Get release artifacts
# uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
# with: with:
# name: artifacts path: artifacts
# path: artifacts merge-multiple: true
# - name: Set release assets and version - name: Set release assets and version
# shell: pwsh shell: pwsh
# run: | run: |
# # Read the first column from the SHA256 file # Read the first column from the SHA256 file
# $windows_sha = Get-Content ./artifacts/managarr-windows.sha256 | ForEach-Object { $_.Split(' ')[0] } $windows_sha = Get-Content ./artifacts/managarr-windows.sha256 | ForEach-Object { $_.Split(' ')[0] }
# Add-Content -Path $env:GITHUB_ENV -Value "WINDOWS_SHA=$windows_sha" Add-Content -Path $env:GITHUB_ENV -Value "WINDOWS_SHA=$windows_sha"
# # Read the release version from the release-version file # Read the release version from the release-version file
# $release_version = Get-Content ./artifacts/release-version $release_version = Get-Content ./artifacts/release-version
# Add-Content -Path $env:GITHUB_ENV -Value "RELEASE_VERSION=$release_version" Add-Content -Path $env:GITHUB_ENV -Value "RELEASE_VERSION=$release_version"
# - name: Validate release environment variables - name: Validate release environment variables
# run: | run: |
# echo "Release SHA windows: ${{ env.WINDOWS_SHA }}" echo "Release SHA windows: ${{ env.WINDOWS_SHA }}"
# echo "Release version: ${{ env.RELEASE_VERSION }}" echo "Release version: ${{ env.RELEASE_VERSION }}"
# - name: Package and Publish package to Chocolatey - name: Package and Publish package to Chocolatey
# run: | run: |
# mkdir ./deployment/chocolatey/tools mkdir ./deployment/chocolatey/tools
# # Run packaging script # Run packaging script
# python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/managarr.nuspec.template" "./deployment/chocolatey/managarr.nuspec" ${{ env.WINDOWS_SHA }} python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/managarr.nuspec.template" "./deployment/chocolatey/managarr.nuspec" ${{ env.WINDOWS_SHA }}
# python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/chocolateyinstall.ps1.template" "./deployment/chocolatey/tools/chocolateyinstall.ps1" ${{ env.WINDOWS_SHA }} python "./deployment/chocolatey/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/chocolatey/chocolateyinstall.ps1.template" "./deployment/chocolatey/tools/chocolateyinstall.ps1" ${{ env.WINDOWS_SHA }}
# # Publish to Chocolatey # Publish to Chocolatey
# cd ./deployment/chocolatey cd ./deployment/chocolatey
# choco pack choco pack
# echo y | choco install managarr -dv -s . echo y | choco install managarr -dv -s .
# $version = managarr --version $version = managarr --version
# $version = $version -replace " ", "." $version = $version -replace " ", "."
# choco push $version.nupkg -s https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }}; choco push $version.nupkg -s https://push.chocolatey.org/ --api-key ${{ secrets.CHOCOLATEY_API_KEY }};
# publish-homebrew-formula: publish-homebrew-formula:
# needs: [publish-github-release] needs: [publish-github-release]
# name: Update Homebrew formulas name: Update Homebrew formulas
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - name: Checkout repository - name: Checkout repository
# uses: actions/checkout@v4 uses: actions/checkout@v4
# with: with:
# fetch-depth: 1 fetch-depth: 1
# - name: Get release artifacts - name: Get release artifacts
# uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
# with: with:
# name: artifacts path: artifacts
# path: artifacts merge-multiple: true
# - name: Set release assets and version - name: Set release assets and version
# shell: bash shell: bash
# run: | run: |
# # Set environment variables # Set environment variables
# macos_sha="$(cat ./artifacts/managarr-macos.sha256 | awk '{print $1}')" macos_sha="$(cat ./artifacts/managarr-macos.sha256 | awk '{print $1}')"
# echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV echo "MACOS_SHA=$macos_sha" >> $GITHUB_ENV
# macos_sha_arm="$(cat ./artifacts/managarr-macos-arm64.sha256 | awk '{print $1}')" macos_sha_arm="$(cat ./artifacts/managarr-macos-arm64.sha256 | awk '{print $1}')"
# echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV echo "MACOS_SHA_ARM=$macos_sha_arm" >> $GITHUB_ENV
# linux_sha="$(cat ./artifacts/managarr-linux-musl.sha256 | awk '{print $1}')" linux_sha="$(cat ./artifacts/managarr-linux-musl.sha256 | awk '{print $1}')"
# echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV echo "LINUX_SHA=$linux_sha" >> $GITHUB_ENV
# release_version="$(cat ./artifacts/release-version)" release_version="$(cat ./artifacts/release-version)"
# echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV echo "RELEASE_VERSION=$release_version" >> $GITHUB_ENV
# - name: Validate release environment variables - name: Validate release environment variables
# run: | run: |
# echo "Release SHA macos: ${{ env.MACOS_SHA }}" echo "Release SHA macos: ${{ env.MACOS_SHA }}"
# echo "Release SHA macos-arm: ${{ env.MACOS_SHA_ARM }}" echo "Release SHA macos-arm: ${{ env.MACOS_SHA_ARM }}"
# echo "Release SHA linux musl: ${{ env.LINUX_SHA }}" echo "Release SHA linux musl: ${{ env.LINUX_SHA }}"
# echo "Release version: ${{ env.RELEASE_VERSION }}" echo "Release version: ${{ env.RELEASE_VERSION }}"
# - name: Execute Homebrew packaging script - name: Execute Homebrew packaging script
# run: | run: |
# # run packaging script # run packaging script
# python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/managarr.rb.template" "./managarr.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }} python "./deployment/homebrew/packager.py" ${{ env.RELEASE_VERSION }} "./deployment/homebrew/managarr.rb.template" "./managarr.rb" ${{ env.MACOS_SHA }} ${{ env.MACOS_SHA_ARM }} ${{ env.LINUX_SHA }}
# - name: Push changes to Homebrew tap - name: Push changes to Homebrew tap
# env: env:
# TOKEN: ${{ secrets.MANAGARR_GITHUB_TOKEN }} TOKEN: ${{ secrets.MANAGARR_GITHUB_TOKEN }}
# run: | run: |
# # push to Git # push to Git
# git config --global user.name "Dark-Alex-17" git config --global user.name "Dark-Alex-17"
# git config --global user.email "alex.j.tusa@gmail.com" git config --global user.email "alex.j.tusa@gmail.com"
# git clone https://Dark-Alex-17:${{ secrets.MANAGARR_GITHUB_TOKEN }}@github.com/Dark-Alex-17/homebrew-managarr.git git clone https://Dark-Alex-17:${{ secrets.MANAGARR_GITHUB_TOKEN }}@github.com/Dark-Alex-17/homebrew-managarr.git
# rm homebrew-managarr/Formula/managarr.rb rm homebrew-managarr/Formula/managarr.rb
# cp managarr.rb homebrew-managarr/Formula cp managarr.rb homebrew-managarr/Formula
# cd homebrew-managarr cd homebrew-managarr
# git add . git add .
# git diff-index --quiet HEAD || git commit -am "Update formula for Managarr release ${{ env.RELEASE_VERSION }}" git diff-index --quiet HEAD || git commit -am "Update formula for Managarr release ${{ env.RELEASE_VERSION }}"
# git push https://$TOKEN@github.com/Dark-Alex-17/homebrew-managarr.git git push https://$TOKEN@github.com/Dark-Alex-17/homebrew-managarr.git
# publish-docker-image: publish-docker-image:
# needs: [publish-github-release] needs: [publish-github-release]
# name: Publishing Docker image to Docker Hub name: Publishing Docker image to Docker Hub
# runs-on: ubuntu-latest runs-on: ubuntu-latest
# steps: steps:
# - name: Checkout repository - name: Checkout repository
# uses: actions/checkout@v4 uses: actions/checkout@v4
# with: with:
# fetch-depth: 1 fetch-depth: 1
# - name: Get release artifacts - name: Get release artifacts
# uses: actions/download-artifact@v3 uses: actions/download-artifact@v4
# with: with:
# name: artifacts path: artifacts
# path: artifacts merge-multiple: true
# - name: Set version variable - name: Ensure repository is up-to-date
# run: | run: |
# version="$(cat artifacts/release-version)" git fetch --all
# echo "version=$version" >> $GITHUB_ENV git pull
# - name: Validate release environment variables - name: Set version variable
# run: | run: |
# echo "Release version: ${{ env.version }}" version="$(cat artifacts/release-version)"
echo "version=$version" >> $GITHUB_ENV
# - name: Set up QEMU - name: Validate release environment variables
# uses: docker/setup-qemu-action@v3 run: |
echo "Release version: ${{ env.version }}"
# - name: Set up Docker Buildx - name: Set up QEMU
# uses: docker/setup-buildx-action@v3 uses: docker/setup-qemu-action@v3
# - name: Login to Docker Hub - name: Set up Docker Buildx
# uses: docker/login-action@v3 uses: docker/setup-buildx-action@v3
# with:
# username: ${{ secrets.DOCKER_USERNAME }}
# password: ${{ secrets.DOCKER_PASSWORD }}
# - name: Push to Docker Hub - name: Login to Docker Hub
# uses: docker/build-push-action@v5 uses: docker/login-action@v3
# with: with:
# context: . username: ${{ secrets.DOCKER_USERNAME }}
# file: Dockerfile password: ${{ secrets.DOCKER_PASSWORD }}
# platforms: linux/amd64,linux/arm64
# push: true
# tags: darkalex17/managarr:latest, darkalex17/managarr:${{ env.version }}
# publish-crate: - name: Push to Docker Hub
# needs: publish-github-release uses: docker/build-push-action@v5
# name: Publish Crate with:
# runs-on: ubuntu-latest context: .
# steps: file: Dockerfile
# - name: Check if actor is repository owner platforms: linux/amd64,linux/arm64
# if: ${{ github.actor != github.repository_owner }} push: true
# run: | tags: darkalex17/managarr:latest, darkalex17/managarr:${{ env.version }}
# echo "You are not authorized to run this workflow."
# exit 1
# - name: Checkout publish-crate:
# uses: actions/checkout@v4 needs: publish-github-release
# with: name: Publish Crate
# fetch-depth: 0 runs-on: ubuntu-latest
steps:
- name: Check if actor is repository owner
if: ${{ github.actor != github.repository_owner }}
run: |
echo "You are not authorized to run this workflow."
exit 1
# - name: Ensure repository is up-to-date - name: Checkout
# run: | uses: actions/checkout@v4
# git fetch --all with:
# git pull fetch-depth: 0
# - uses: actions/cache@v3 - name: Ensure repository is up-to-date
# name: Cache Cargo registry run: |
# with: git fetch --all
# path: ~/.cargo/registry git pull
# key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
# - uses: actions/cache@v3 - uses: actions/cache@v3
# with: name: Cache Cargo registry
# path: ~/.cargo/bin with:
# key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }} path: ~/.cargo/registry
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
# - name: Install Rust stable - uses: actions/cache@v3
# uses: dtolnay/rust-toolchain@stable with:
path: ~/.cargo/bin
key: ${{ runner.os }}-cargo-bin-${{ hashFiles('.github/workflows/release.yml') }}
# - uses: katyo/publish-crates@v2 - name: Install Rust stable
# with: uses: dtolnay/rust-toolchain@stable
# registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
- uses: katyo/publish-crates@v2
with:
registry-token: ${{ secrets.CARGO_REGISTRY_TOKEN }}
+39 -39
View File
@@ -48,51 +48,51 @@ jobs:
- name: cargo test --locked - name: cargo test --locked
run: cargo test --locked --all-features --all-targets run: cargo test --locked --all-features --all-targets
minimal-versions: # minimal-versions:
# This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure # # This action chooses the oldest version of the dependencies permitted by Cargo.toml to ensure
# that this crate is compatible with the minimal version that this crate and its dependencies # # that this crate is compatible with the minimal version that this crate and its dependencies
# require. This will pickup issues where this create relies on functionality that was introduced # # require. This will pickup issues where this create relies on functionality that was introduced
# later than the actual version specified (e.g., when we choose just a major version, but a # # later than the actual version specified (e.g., when we choose just a major version, but a
# method was added after this version). # # method was added after this version).
# # #
# This particular check can be difficult to get to succeed as often transitive dependencies may # # This particular check can be difficult to get to succeed as often transitive dependencies may
# be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There # # be incorrectly specified (e.g., a dependency specifies 1.0 but really requires 1.1.5). There
# is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for # # is an alternative flag available -Zdirect-minimal-versions that uses the minimal versions for
# direct dependencies of this crate, while selecting the maximal versions for the transitive # # direct dependencies of this crate, while selecting the maximal versions for the transitive
# dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase # # dependencies. Alternatively, you can add a line in your Cargo.toml to artificially increase
# the minimal dependency, which you do with e.g.: # # the minimal dependency, which you do with e.g.:
# ```toml # # ```toml
# # for minimal-versions # # # for minimal-versions
# [target.'cfg(any())'.dependencies] # # [target.'cfg(any())'.dependencies]
# openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions # # openssl = { version = "0.10.55", optional = true } # needed to allow foo to build with -Zminimal-versions
# ``` # # ```
# The optional = true is necessary in case that dependency isn't otherwise transitively required # # The optional = true is necessary in case that dependency isn't otherwise transitively required
# by your library, and the target bit is so that this dependency edge never actually affects # # by your library, and the target bit is so that this dependency edge never actually affects
# Cargo build order. See also # # Cargo build order. See also
# https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49. # # https://github.com/jonhoo/fantoccini/blob/fde336472b712bc7ebf5b4e772023a7ba71b2262/Cargo.toml#L47-L49.
# This action is run on ubuntu with the stable toolchain, as it is not expected to fail # # This action is run on ubuntu with the stable toolchain, as it is not expected to fail
runs-on: ubuntu-latest # runs-on: ubuntu-latest
name: ubuntu / stable / minimal-versions # name: ubuntu / stable / minimal-versions
steps: # steps:
- uses: actions/checkout@v4 # - uses: actions/checkout@v4
- name: Install Rust stable # - name: Install Rust stable
uses: dtolnay/rust-toolchain@stable # uses: dtolnay/rust-toolchain@stable
- name: Install nightly for -Zdirect-minimal-versions # - name: Install nightly for -Zdirect-minimal-versions
uses: dtolnay/rust-toolchain@nightly # uses: dtolnay/rust-toolchain@nightly
- name: rustup default stable # - name: rustup default stable
run: rustup default stable # run: rustup default stable
- name: cargo update -Zdirect-minimal-versions # - name: cargo update -Zdirect-minimal-versions
run: cargo +nightly update -Zdirect-minimal-versions # run: cargo +nightly update -Zdirect-minimal-versions
- name: cargo test # - name: cargo test
run: cargo test --locked --all-features --all-targets # run: cargo test --locked --all-features --all-targets
- name: Cache Cargo dependencies # - name: Cache Cargo dependencies
uses: Swatinem/rust-cache@v2 # uses: Swatinem/rust-cache@v2
os-check: os-check:
# run cargo test on mac and windows # run cargo test on mac and windows
+30
View File
@@ -5,6 +5,36 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## v0.5.1 (2025-03-01)
### Feat
- CLI Support for multiple Servarr instances
- Support for multiple servarr definitions - no tests [skip ci]
- Support for loading Servarr API tokens from a file
- Tweaked the implementation for environment variables in the config a bit
- var interpolation
### Fix
- Updated openssl to 0.10.70 to mitigate CVE-2025-24898
- Addressed rustfmt complaints
- Corrected typo in the managarr.nuspec.template
### Refactor
- Updated dependencies
- Addressed Cargo fmt complaints
- Added a debug line for logging to output the config used when starting Managarr
- Updated the 2018 idiom lint to the 2021_compatibility lint
- Removed unnecessary clones in the networking module to speed up network request handling
- Corrected some clone instead of copy behaviors in the command line handlers
- Removed unnecessary clone from stateful table
- Removed unnecessary clone call from extract_and_add_tag_ids_vec method
- Reduced the number of clones necessary when building modal structs
- Refactored a handful of Option calls to use take instead
- Renamed KeyEventHandler::with to KeyEventHandler::new to keep with Rust best practices and conventions
## v0.4.2 (2024-12-21) ## v0.4.2 (2024-12-21)
### Fix ### Fix
+17
View File
@@ -1,6 +1,23 @@
# Contributing # Contributing
Contributors are very welcome! **No contribution is too small and all contributions are valued.** Contributors are very welcome! **No contribution is too small and all contributions are valued.**
## License and Attribution
#### _If you plan on contributing to the base project, no attribution is needed!_ Feel free to proceed to the [next steps](CONTRIBUTING.md#Rust).
Otherwise, below are key points to understand from the [Managarr License, Version 1.0](LICENSE):
1. **Non-Commercial Use**:
- Managarr is licensed solely for non-commercial purposes. Any commercial use of Managarr (e.g., selling or offering as a paid service) requires separate permission.
2. **Attribution when Forking and Redistributing Without Contributing back to Main Project**:
- **If you fork the project and distribute it separately** (e.g., publish or _publicly_ host it independently from the original project), you are required to provide attribution.
- You may credit the original author by using any of the following phrasing:
- "Thanks to Alexander J. Clarke (Dark-Alex-17) for creating the original Managarr project!"
- "Forked from the Managarr project, created by Alexander J. Clarke (Dark-Alex-17)"
- "This software is based on the original Managarr project by Alexander J. Clarke (Dark-Alex-17)"
- "Inspired by Alexander J. Clarke (Dark-Alex-17)'s Managarr project"
- If changes are made to the base Managarr project, please note those modifications and provide the new attribution accordingly.
## Rust ## Rust
You'll need to have the stable Rust toolchain installed in order to develop Managarr. You'll need to have the stable Rust toolchain installed in order to develop Managarr.
Generated
+457 -236
View File
File diff suppressed because it is too large Load Diff
+19 -7
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "managarr" name = "managarr"
version = "0.4.2" version = "0.5.1"
authors = ["Alex Clarke <alex.j.tusa@gmail.com>"] authors = ["Alex Clarke <alex.j.tusa@gmail.com>"]
description = "A TUI and CLI to manage your Servarrs" description = "A TUI and CLI to manage your Servarrs"
keywords = ["managarr", "ratatui", "dashboard", "servarr", "tui"] keywords = ["managarr", "ratatui", "dashboard", "servarr", "tui"]
@@ -10,9 +10,12 @@ homepage = "https://github.com/Dark-Alex-17/managarr"
readme = "README.md" readme = "README.md"
edition = "2021" edition = "2021"
license = "MIT" license = "MIT"
rust-version = "1.82.0" rust-version = "1.85.0"
exclude = [".github", "CONTRIBUTING.md", "*.log", "tags"] exclude = [".github", "CONTRIBUTING.md", "*.log", "tags"]
[workspace]
members = ["proc_macros/enum_display_style_derive", "proc_macros/validate_theme_derive"]
[dependencies] [dependencies]
anyhow = "1.0.68" anyhow = "1.0.68"
backtrace = "0.3.74" backtrace = "0.3.74"
@@ -41,11 +44,16 @@ ratatui = { version = "0.29.0", features = [
"unstable-widget-ref", "unstable-widget-ref",
] } ] }
urlencoding = "2.1.2" urlencoding = "2.1.2"
clap = { version = "4.5.20", features = ["derive", "cargo", "env"] } clap = { version = "4.5.20", features = [
"derive",
"cargo",
"env",
"wrap_help",
] }
clap_complete = "4.5.33" clap_complete = "4.5.33"
itertools = "0.13.0" itertools = "0.14.0"
ctrlc = "3.4.5" ctrlc = "3.4.5"
colored = "2.1.0" colored = "3.0.0"
async-trait = "0.1.83" async-trait = "0.1.83"
dirs-next = "2.0.0" dirs-next = "2.0.0"
managarr-tree-widget = "0.24.0" managarr-tree-widget = "0.24.0"
@@ -53,14 +61,18 @@ indicatif = "0.17.9"
derive_setters = "0.1.6" derive_setters = "0.1.6"
deunicode = "1.6.0" deunicode = "1.6.0"
paste = "1.0.15" paste = "1.0.15"
openssl = { version = "0.10.68", features = ["vendored"] } openssl = { version = "0.10.70", features = ["vendored"] }
veil = "0.2.0"
validate_theme_derive = { path = "proc_macros/validate_theme_derive" }
enum_display_style_derive = { path = "proc_macros/enum_display_style_derive" }
[dev-dependencies] [dev-dependencies]
assert_cmd = "2.0.16" assert_cmd = "2.0.16"
mockall = "0.13.0" mockall = "0.13.0"
mockito = "1.0.0" mockito = "1.0.0"
pretty_assertions = "1.3.0" pretty_assertions = "1.3.0"
rstest = "0.23.0" rstest = "0.25.0"
serial_test = "3.2.0"
[dev-dependencies.cargo-husky] [dev-dependencies.cargo-husky]
version = "1" version = "1"
+1 -1
View File
@@ -1,4 +1,4 @@
FROM rust:1.82 AS builder FROM rust:1.85 AS builder
WORKDIR /usr/src WORKDIR /usr/src
# Download and compile Rust dependencies in an empty project and cache as a separate Docker layer # Download and compile Rust dependencies in an empty project and cache as a separate Docker layer
+47 -10
View File
@@ -1,16 +1,53 @@
MIT License Managarr License
Version 1.0, 2025
Copyright (c) 2023 Alexander J. Clarke Copyright (c) 2025 Alexander J. Clarke (Dark-Alex-17)
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to use,
in the Software without restriction, including without limitation the rights copy, modify, merge, publish, and distribute the Software solely for
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell non-commercial purposes, subject to the following conditions:
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all 1. Attribution:
copies or substantial portions of the Software. - The above copyright notice, this permission notice, and a prominent notice stating
that the Software is part of the "Managarr" project shall be included in all copies or
substantial portions of the Software **when the Software is forked and redistributed separately** from the original project.
- If you fork the software and **distribute it separately** without merging it back into the original base project (the Managarr repository), you must provide attribution to the original author.
You may use any of the following forms of attribution:
- "Thanks to Alexander J. Clarke (Dark-Alex-17) for creating the original Managarr project!"
- "Forked from the Managarr project, created by Alexander J. Clarke (Dark-Alex-17)"
- "This software is based on the original Managarr project by Alexander J. Clarke (Dark-Alex-17)"
- "Inspired by Alexander J. Clarke (Dark-Alex-17)'s Managarr project"
- If you modify the software, the attribution must also note that changes were made and describe those modifications, if feasible.
2. Non-Commercial Use Only:
The use of this Software for commercial purposes, including but not limited
to sale, licensing, or use in any product or service for monetary
compensation, is strictly prohibited without prior written permission from
Alexander J. Clarke (Dark-Alex-17).
For avoidance of doubt:
- **Allowed:** Private use, educational purposes, research, or any usage
that does not directly generate revenue.
- **Prohibited:** Selling, sublicensing, or incorporating the Software into
commercial products or services.
3. Modifications and Derivatives:
- Any modifications or derivative works based on this Software must clearly
document all changes made and prominently credit the original "Managarr"
project as described in section 1.
- Derivative works must retain this license, the original copyright notice,
and all terms and conditions described herein. This applies to the entire
derivative work, even if combined with other software.
4. Warranty Disclaimer:
This Software is provided "as is," without warranty of any kind, express
or implied, including but not limited to the warranties of merchantability,
fitness for a particular purpose, and noninfringement. In no event shall the
authors or copyright holders be liable for any claim, damages, or other
liability, whether in an action of contract, tort, or otherwise, arising
from, out of, or in connection with the Software or the use or other
dealings in the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+1 -1
View File
@@ -8,7 +8,7 @@ default: run
.PHONY: test test-cov build run lint lint-fix fmt analyze sonar release delete-tag .PHONY: test test-cov build run lint lint-fix fmt analyze sonar release delete-tag
test: test:
@cargo test @cargo test --all
## Run all tests with coverage - `cargo install cargo-tarpaulin` ## Run all tests with coverage - `cargo install cargo-tarpaulin`
test-cov: test-cov:
+114 -35
View File
@@ -1,7 +1,7 @@
# managarr - A TUI and CLI to manage your Servarrs # managarr - A TUI and CLI to manage your Servarrs
![check](https://github.com/Dark-Alex-17/managarr/actions/workflows/check.yml/badge.svg) ![Check](https://github.com/Dark-Alex-17/managarr/actions/workflows/check.yml/badge.svg)
![test](https://github.com/Dark-Alex-17/managarr/actions/workflows/test.yml/badge.svg) ![Test](https://github.com/Dark-Alex-17/managarr/actions/workflows/test.yml/badge.svg)
![License](https://img.shields.io/badge/license-MIT-blueviolet.svg) ![License](https://img.shields.io/badge/license-MIT-blueviolet.svg)
![LOC](https://tokei.rs/b1/github/Dark-Alex-17/managarr?category=code) ![LOC](https://tokei.rs/b1/github/Dark-Alex-17/managarr?category=code)
[![crates.io link](https://img.shields.io/crates/v/managarr.svg)](https://crates.io/crates/managarr) [![crates.io link](https://img.shields.io/crates/v/managarr.svg)](https://crates.io/crates/managarr)
@@ -10,6 +10,8 @@
![Crate.io downloads](https://img.shields.io/crates/d/managarr?label=Crate%20downloads) ![Crate.io downloads](https://img.shields.io/crates/d/managarr?label=Crate%20downloads)
[![GitHub Downloads](https://img.shields.io/github/downloads/Dark-Alex-17/managarr/total.svg?label=GitHub%20downloads)](https://github.com/Dark-Alex-17/managarr/releases) [![GitHub Downloads](https://img.shields.io/github/downloads/Dark-Alex-17/managarr/total.svg?label=GitHub%20downloads)](https://github.com/Dark-Alex-17/managarr/releases)
![Docker pulls](https://img.shields.io/docker/pulls/darkalex17/managarr?label=Docker%20downloads) ![Docker pulls](https://img.shields.io/docker/pulls/darkalex17/managarr?label=Docker%20downloads)
[![Matrix](https://img.shields.io/matrix/managarr-room%3Amatrix.org?logo=matrix&server_fqdn=matrix.org&fetchMode=guest&style=social&label=Managarr%20Matrix%20Space&link=https%3A%2F%2Fmatrix.to%2F%23%2F%23managarr%3Amatrix.org)](https://matrix.to/#/#managarr:matrix.org)
Managarr is a TUI and CLI to help you manage your HTPC (Home Theater PC). Built with 🤎 in Rust! Managarr is a TUI and CLI to help you manage your HTPC (Home Theater PC). Built with 🤎 in Rust!
@@ -76,6 +78,16 @@ To upgrade to a newer version of Managarr:
brew upgrade managarr brew upgrade managarr
``` ```
### Nix (Externally Maintained)
To install Managarr on NixOS, you can use the following command:
```shell
nix-env --install managarr
# Alternatively, for non-NixOS users, you can spawn a temporary shell with Managarr available like so:
nix-shell -p managarr
```
### Chocolatey (Windows) ### Chocolatey (Windows)
The Managarr Chocolatey package is located [here](https://community.chocolatey.org/packages/managarr). Please note that validation The Managarr Chocolatey package is located [here](https://community.chocolatey.org/packages/managarr). Please note that validation
of Chocolatey packages take quite some time, and thus the package may not be available immediately after a new release. of Chocolatey packages take quite some time, and thus the package may not be available immediately after a new release.
@@ -84,7 +96,7 @@ of Chocolatey packages take quite some time, and thus the package may not be ava
choco install managarr choco install managarr
# Some newer releases may require a version number, so you can specify it like so: # Some newer releases may require a version number, so you can specify it like so:
choco install managarr --version=0.4.1 choco install managarr --version=0.5.0
``` ```
To upgrade to the latest and greatest version of Managarr: To upgrade to the latest and greatest version of Managarr:
@@ -92,7 +104,7 @@ To upgrade to the latest and greatest version of Managarr:
choco upgrade managarr choco upgrade managarr
# To upgrade to a specific version: # To upgrade to a specific version:
choco upgrade managarr --version=0.4.2 choco upgrade managarr --version=0.5.0
``` ```
### Manual ### Manual
@@ -194,6 +206,16 @@ Key:
- [ ] Support for Tautulli - [ ] Support for Tautulli
### Themes
Managarr ships with a few themes out of the box. Here's a few examples:
![default](themes/default/manual_episode_search.png)
![dracula](themes/dracula/manual_episode_search.png)
![watermelon-dark](themes/watermelon-dark/manual_episode_search.png)
You can also create your own custom themes as well. To learn more about what themes are built-in to Managarr and how
to create your own custom themes, check out the [Themes README](themes/README.md).
### The Managarr CLI ### The Managarr CLI
Managarr can be used in one of two ways: As a TUI, or as a CLI for managing your Servarrs. Managarr can be used in one of two ways: As a TUI, or as a CLI for managing your Servarrs.
@@ -206,7 +228,7 @@ To see all available commands, simply run `managarr --help`:
```shell ```shell
$ managarr --help $ managarr --help
managarr 0.4.0 managarr 0.5.1
Alex Clarke <alex.j.tusa@gmail.com> Alex Clarke <alex.j.tusa@gmail.com>
A TUI and CLI to manage your Servarrs A TUI and CLI to manage your Servarrs
@@ -221,10 +243,15 @@ Commands:
help Print this message or the help of the given subcommand(s) help Print this message or the help of the given subcommand(s)
Options: Options:
--disable-spinner Disable the spinner (can sometimes make parsing output challenging) [env: MANAGARR_DISABLE_SPINNER=] --disable-spinner Disable the spinner (can sometimes make parsing output challenging) [env: MANAGARR_DISABLE_SPINNER=]
--config <CONFIG> The Managarr configuration file to use [env: MANAGARR_CONFIG_FILE=] --config-file <CONFIG_FILE> The Managarr configuration file to use [env: MANAGARR_CONFIG_FILE=]
-h, --help Print help --themes-file <THEMES_FILE> The Managarr themes file to use [env: MANAGARR_THEMES_FILE=]
-V, --version Print version --theme <THEME> The name of the Managarr theme to use [env: MANAGARR_THEME=]
--servarr-name <SERVARR_NAME> For multi-instance configurations, you need to specify the name of the instance configuration that you want to use.
This is useful when you have multiple instances of the same Servarr defined in your config file.
By default, if left empty, the first configured Servarr instance listed in the config file will be used.
-h, --help Print help
-V, --version Print version
``` ```
All subcommands also have detailed help menus to show you how to use them. For example, to see all available commands for Sonarr, you would run: All subcommands also have detailed help menus to show you how to use them. For example, to see all available commands for Sonarr, you would run:
@@ -295,44 +322,96 @@ where you may have more than one instance of a given Servarr running. Thus, you
config file using the `--config` flag: config file using the `--config` flag:
```shell ```shell
managarr --config /path/to/config.yml managarr --config-file /path/to/config.yml
``` ```
### Example Configuration: ### Example Configuration:
```yaml ```yaml
theme: default
radarr: radarr:
host: 192.168.0.78 - host: 192.168.0.78
port: 7878 port: 7878
api_token: someApiToken1234567890 api_token: someApiToken1234567890
ssl_cert_path: /path/to/radarr.crt # Required to enable SSL ssl_cert_path: /path/to/radarr.crt # Required to enable SSL
sonarr: sonarr:
uri: http://htpc.local/sonarr # Example of using the 'uri' key instead of 'host' and 'port' - uri: http://htpc.local/sonarr # Example of using the 'uri' key instead of 'host' and 'port'
api_token: someApiToken1234567890 api_token: someApiToken1234567890
- name: Anime Sonarr # An example of a custom name for a secondary Sonarr instance
host: 192.168.0.89
port: 8989
api_token: someApiToken1234567890
readarr: readarr:
host: 192.168.0.87 - host: 192.168.0.87
port: 8787 port: 8787
api_token: someApiToken1234567890 api_token_file: /root/.config/readarr_api_token # Example of loading the API token from a file instead of hardcoding it in the configuration file
lidarr: lidarr:
host: 192.168.0.86 - host: 192.168.0.86
port: 8686 port: 8686
api_token: someApiToken1234567890 api_token: ${MY_LIDARR_API_TOKEN} # Example of configuring using environment variables
whisparr: whisparr:
host: 192.168.0.69 - host: 192.168.0.69
port: 6969 port: 6969
api_token: someApiToken1234567890 api_token: someApiToken1234567890
ssl_cert_path: /path/to/whisparr.crt ssl_cert_path: /path/to/whisparr.crt
bazarr: bazarr:
host: 192.168.0.67 - host: 192.168.0.67
port: 6767 port: 6767
api_token: someApiToken1234567890 api_token: someApiToken1234567890
prowlarr: prowlarr:
host: 192.168.0.96 - host: 192.168.0.96
port: 9696 port: 9696
api_token: someApiToken1234567890 api_token: someApiToken1234567890
tautulli: tautulli:
host: 192.168.0.81 - host: 192.168.0.81
port: 8181 port: 8181
api_token: someApiToken1234567890 api_token: someApiToken1234567890
```
### Example Multi-Instance Configuration:
```yaml
theme: default
radarr:
- host: 192.168.0.78 # No name specified, so this instance's name will default to 'Radarr 1'
port: 7878
api_token: someApiToken1234567890
ssl_cert_path: /path/to/radarr.crt
- name: International Movies
host: 192.168.0.79
port: 7878
api_token: someApiToken1234567890
sonarr:
- name: Anime
weight: 1 # This instance will be the first tab in the TUI
uri: http://htpc.local/sonarr
api_token: someApiToken1234567890
- name: TV Shows
weight: 2 # This instance will be the second tab in the TUI
host: 192.168.0.89
port: 8989
api_token: someApiToken1234567890
```
In this configuration, you can see that we have multiple instances of Radarr and Sonarr configured. The `weight` key is
used to specify the order in which the tabs will appear in the TUI. The lower the weight, the further to the left the
tab will appear. If no weight is specified, then tabs will be ordered in the order they appear in the configuration
file.
When no `name` is specified for a Servarr instance, the name will default to the name of the Servarr with a number
appended to it. For example, if you have two Radarr instances and neither has a name, they will be named `Radarr 1` and
`Radarr 2`, respectively.
In this example configuration, the tabs in the TUI would appear as follows:
`Anime | TV Shows | Radarr 1 | International Movies`
### Specify Which Servarr Instance to Use in the CLI
If you have multiple instances of the same Servarr running, you can specify which instance you want to use by using the `--servarr-name` flag:
```shell
managarr --servarr-name "International Movies"
``` ```
## Environment Variables ## Environment Variables
+9
View File
@@ -1,5 +1,14 @@
coverage: coverage:
range: "80..100" range: "80..100"
status:
project:
default:
threshold: 0
target: 80%
patch:
default:
threshold: 0
target: 80%
ignore: ignore:
- "**/*_tests.rs" - "**/*_tests.rs"
@@ -35,7 +35,7 @@ This is a nuspec. It mostly adheres to https://docs.nuget.org/create/Nuspec-Refe
<tags>cli cross-platform terminal servarr tui sonarr radarr rust</tags> <tags>cli cross-platform terminal servarr tui sonarr radarr rust</tags>
<summary>A TUI and CLI for managing *arr servers.</summary> <summary>A TUI and CLI for managing *arr servers.</summary>
<description> <description>
A TUI and CLI for managing *arr servers. Build with love in Rust! A TUI and CLI for managing *arr servers. Built with love in Rust!
**Usage** **Usage**
To use, run `managarr` in a terminal. To use, run `managarr` in a terminal.
@@ -0,0 +1,12 @@
[package]
name = "enum_display_style_derive"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
quote = "1.0.39"
syn = "2.0.99"
darling = "0.20.10"
@@ -0,0 +1,76 @@
mod macro_models;
use crate::macro_models::DisplayStyleArgs;
use darling::FromVariant;
use quote::quote;
use syn::{Data, DeriveInput, parse_macro_input};
/// Derive macro for generating a `to_display_str` method for an enum.
///
/// # Example
///
/// Using default values for the display style:
///
/// ```
/// use enum_display_style_derive::EnumDisplayStyle;
///
/// #[derive(EnumDisplayStyle)]
/// enum Weekend {
/// Saturday,
/// Sunday,
/// }
///
/// assert_eq!(Weekend::Saturday.to_display_str(), "Saturday");
/// assert_eq!(Weekend::Sunday.to_display_str(), "Sunday");
/// ```
///
/// Using custom values for the display style:
///
/// ```
/// use enum_display_style_derive::EnumDisplayStyle;
///
/// #[derive(EnumDisplayStyle)]
/// enum MonitorStatus {
/// #[display_style(name = "Monitor Transactions")]
/// Active,
/// #[display_style(name = "Don't Monitor Transactions")]
/// None,
/// }
///
/// assert_eq!(MonitorStatus::Active.to_display_str(), "Monitor Transactions");
/// assert_eq!(MonitorStatus::None.to_display_str(), "Don't Monitor Transactions");
/// ```
#[proc_macro_derive(EnumDisplayStyle, attributes(display_style))]
pub fn enum_display_style_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let enum_name = &input.ident;
let mut match_arms = Vec::new();
if let Data::Enum(data_enum) = &input.data {
let variants = &data_enum.variants;
for variant in variants {
let variant_ident = &variant.ident;
let variant_display_name = DisplayStyleArgs::from_variant(variant)
.unwrap()
.name
.unwrap_or_else(|| variant_ident.to_string());
match_arms.push(quote! {
#enum_name::#variant_ident => #variant_display_name,
});
}
}
quote! {
impl<'a> #enum_name {
pub fn to_display_str(self) -> &'a str {
match self {
#(#match_arms)*
}
}
}
}
.into()
}
@@ -0,0 +1,7 @@
use darling::FromVariant;
#[derive(Debug, FromVariant)]
#[darling(attributes(display_style))]
pub struct DisplayStyleArgs {
pub name: Option<String>,
}
@@ -0,0 +1,14 @@
[package]
name = "validate_theme_derive"
version = "0.1.0"
edition = "2024"
[lib]
proc-macro = true
[dependencies]
quote = "1.0.39"
syn = "2.0.99"
[dev-dependencies]
log = "0.4.17"
@@ -0,0 +1,106 @@
use proc_macro::TokenStream;
use quote::quote;
use syn::{Data, DeriveInput, Fields, parse_macro_input};
/// Derive macro for generating a `validate` method for a Theme struct.
/// The `validate` method ensures that all values with the `validate` attribute are not `None`.
/// Otherwise, an error message it output to both the log file and stdout and the program exits.
///
/// # Example
///
/// Valid themes pass through the program transitively without any messages being output.
///
/// ```
/// use validate_theme_derive::ValidateTheme;
///
/// #[derive(ValidateTheme, Default)]
/// struct Theme {
/// pub name: String,
/// #[validate]
/// pub good: Option<Style>,
/// #[validate]
/// pub bad: Option<Style>,
/// pub ugly: Option<Style>,
/// }
///
/// struct Style {
/// color: String,
/// }
///
/// let theme = Theme {
/// good: Some(Style { color: "Green".to_owned() }),
/// bad: Some(Style { color: "Red".to_owned() }),
/// ..Theme::default()
/// };
///
/// // Since only `good` and `bad` have the `validate` attribute, the `validate` method will only check those fields.
/// theme.validate();
/// // Since both `good` and `bad` have values, the program will not exit and no message is output.
/// ```
///
/// Invalid themes will output an error message to both the log file and stdout and the program will exit.
///
/// ```should_panic
/// use validate_theme_derive::ValidateTheme;
///
/// #[derive(ValidateTheme, Default)]
/// struct Theme {
/// pub name: String,
/// #[validate]
/// pub good: Option<Style>,
/// #[validate]
/// pub bad: Option<Style>,
/// pub ugly: Option<Style>,
/// }
///
/// struct Style {
/// color: String,
/// }
///
/// let theme = Theme {
/// bad: Some(Style { color: "Red".to_owned() }),
/// ..Theme::default()
/// };
///
/// // Since `good` has the `validate` attribute and since `good` is `None`, the `validate` method will output an error message and exit the program.
/// theme.validate();
/// ```
#[proc_macro_derive(ValidateTheme, attributes(validate))]
pub fn derive_validate_theme(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let struct_name = &input.ident;
let mut validation_checks = Vec::new();
if let Data::Struct(data_struct) = &input.data {
if let Fields::Named(fields) = &data_struct.fields {
for field in &fields.named {
let field_name = &field.ident;
let has_validate_attr = field
.attrs
.iter()
.any(|attr| attr.path().is_ident("validate"));
if has_validate_attr {
validation_checks.push(quote! {
if self.#field_name.is_none() {
log::error!("{} is missing a color value.", stringify!(#field_name));
eprintln!("{} is missing a color value.", stringify!(#field_name));
std::process::exit(1);
}
})
}
}
}
}
quote! {
impl #struct_name {
pub fn validate(&self) {
#(#validation_checks)*
}
}
}
.into()
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 382 KiB

After

Width:  |  Height:  |  Size: 340 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 211 KiB

After

Width:  |  Height:  |  Size: 241 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 203 KiB

After

Width:  |  Height:  |  Size: 220 KiB

+249 -68
View File
@@ -1,13 +1,12 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::models::Route;
use anyhow::anyhow; use anyhow::anyhow;
use pretty_assertions::assert_eq; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest; use serial_test::serial;
use tokio::sync::mpsc; use tokio::sync::mpsc;
use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES}; use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES};
use crate::app::{App, AppConfig, Data, ServarrConfig}; use crate::app::{interpolate_env_vars, App, AppConfig, Data, ServarrConfig};
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, RadarrData};
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, SonarrData};
use crate::models::{HorizontallyScrollableText, TabRoute}; use crate::models::{HorizontallyScrollableText, TabRoute};
@@ -15,37 +14,69 @@ mod tests {
use crate::network::NetworkEvent; use crate::network::NetworkEvent;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
#[rstest] #[test]
fn test_app_new( fn test_app_new() {
#[values(ActiveRadarrBlock::default(), ActiveSonarrBlock::default())] servarr: impl Into<Route> let radarr_config_1 = ServarrConfig {
+ Copy, name: Some("Radarr Test".to_owned()),
) { ..ServarrConfig::default()
let (title, config) = match servarr.into() {
Route::Radarr(_, _) => (
"Radarr",
AppConfig {
radarr: Some(ServarrConfig::default()),
..AppConfig::default()
},
),
Route::Sonarr(_, _) => (
"Sonarr",
AppConfig {
sonarr: Some(ServarrConfig::default()),
..AppConfig::default()
},
),
_ => unreachable!(),
}; };
let tab_route = |title: &'static str| TabRoute { let radarr_config_2 = ServarrConfig {
title, weight: Some(3),
route: servarr.into(), ..ServarrConfig::default()
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
}; };
let sonarr_config_1 = ServarrConfig {
name: Some("Sonarr Test".to_owned()),
weight: Some(1),
..ServarrConfig::default()
};
let sonarr_config_2 = ServarrConfig::default();
let config = AppConfig {
theme: None,
radarr: Some(vec![radarr_config_1.clone(), radarr_config_2.clone()]),
sonarr: Some(vec![sonarr_config_1.clone(), sonarr_config_2.clone()]),
};
let expected_tab_routes = vec![
TabRoute {
title: "Sonarr Test".to_owned(),
route: ActiveSonarrBlock::default().into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(sonarr_config_1),
},
TabRoute {
title: "Radarr 1".to_owned(),
route: ActiveRadarrBlock::default().into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(radarr_config_2),
},
TabRoute {
title: "Radarr Test".to_owned(),
route: ActiveRadarrBlock::default().into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(radarr_config_1),
},
TabRoute {
title: "Sonarr 1".to_owned(),
route: ActiveSonarrBlock::default().into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(sonarr_config_2),
},
];
let app = App::new( let app = App::new(
mpsc::channel::<NetworkEvent>(500).0, mpsc::channel::<NetworkEvent>(500).0,
@@ -54,13 +85,13 @@ mod tests {
); );
assert!(app.navigation_stack.is_empty()); assert!(app.navigation_stack.is_empty());
assert_eq!(app.get_current_route(), servarr.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::default().into());
assert!(app.network_tx.is_some()); assert!(app.network_tx.is_some());
assert!(!app.cancellation_token.is_cancelled()); assert!(!app.cancellation_token.is_cancelled());
assert!(app.is_first_render); assert!(app.is_first_render);
assert_eq!(app.error, HorizontallyScrollableText::default()); assert_eq!(app.error, HorizontallyScrollableText::default());
assert_eq!(app.server_tabs.index, 0); assert_eq!(app.server_tabs.index, 0);
assert_eq!(app.server_tabs.tabs, vec![tab_route(title)]); assert_eq!(app.server_tabs.tabs, expected_tab_routes);
assert_eq!(app.tick_until_poll, 400); assert_eq!(app.tick_until_poll, 400);
assert_eq!(app.ticks_until_scroll, 4); assert_eq!(app.ticks_until_scroll, 4);
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -81,29 +112,6 @@ mod tests {
assert!(app.is_first_render); assert!(app.is_first_render);
assert_eq!(app.error, HorizontallyScrollableText::default()); assert_eq!(app.error, HorizontallyScrollableText::default());
assert_eq!(app.server_tabs.index, 0); assert_eq!(app.server_tabs.index, 0);
assert_eq!(
app.server_tabs.tabs,
vec![
TabRoute {
title: "Radarr",
route: ActiveRadarrBlock::Movies.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
},
TabRoute {
title: "Sonarr",
route: ActiveSonarrBlock::Series.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
},
]
);
assert_eq!(app.tick_until_poll, 400); assert_eq!(app.tick_until_poll, 400);
assert_eq!(app.ticks_until_scroll, 4); assert_eq!(app.ticks_until_scroll, 4);
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -116,7 +124,7 @@ mod tests {
#[test] #[test]
fn test_navigation_stack_methods() { fn test_navigation_stack_methods() {
let mut app = App::default(); let mut app = App::test_default();
let default_route = app.server_tabs.tabs.first().unwrap().route; let default_route = app.server_tabs.tabs.first().unwrap().route;
assert_eq!(app.get_current_route(), default_route); assert_eq!(app.get_current_route(), default_route);
@@ -153,7 +161,7 @@ mod tests {
let mut app = App { let mut app = App {
is_loading: true, is_loading: true,
should_refresh: false, should_refresh: false,
..App::default() ..App::test_default()
}; };
app.cancellation_token.cancel(); app.cancellation_token.cancel();
@@ -171,7 +179,7 @@ mod tests {
fn test_reset_tick_count() { fn test_reset_tick_count() {
let mut app = App { let mut app = App {
tick_count: 2, tick_count: 2,
..App::default() ..App::test_default()
}; };
app.reset_tick_count(); app.reset_tick_count();
@@ -198,7 +206,7 @@ mod tests {
error: "Test error".to_owned().into(), error: "Test error".to_owned().into(),
is_first_render: false, is_first_render: false,
data, data,
..App::default() ..App::test_default()
}; };
app.reset(); app.reset();
@@ -212,7 +220,7 @@ mod tests {
#[test] #[test]
fn test_handle_error() { fn test_handle_error() {
let mut app = App::default(); let mut app = App::test_default();
let test_string = "Testing"; let test_string = "Testing";
app.handle_error(anyhow!(test_string)); app.handle_error(anyhow!(test_string));
@@ -231,7 +239,7 @@ mod tests {
let mut app = App { let mut app = App {
tick_until_poll: 2, tick_until_poll: 2,
network_tx: Some(sync_network_tx), network_tx: Some(sync_network_tx),
..App::default() ..App::test_default()
}; };
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -255,7 +263,7 @@ mod tests {
tick_until_poll: 2, tick_until_poll: 2,
network_tx: Some(sync_network_tx), network_tx: Some(sync_network_tx),
is_first_render: true, is_first_render: true,
..App::default() ..App::test_default()
}; };
assert_eq!(app.tick_count, 0); assert_eq!(app.tick_count, 0);
@@ -309,7 +317,7 @@ mod tests {
tick_until_poll: 2, tick_until_poll: 2,
tick_count: 2, tick_count: 2,
is_routing: true, is_routing: true,
..App::default() ..App::test_default()
}; };
app.on_tick().await; app.on_tick().await;
@@ -322,7 +330,7 @@ mod tests {
tick_until_poll: 2, tick_until_poll: 2,
tick_count: 2, tick_count: 2,
should_refresh: true, should_refresh: true,
..App::default() ..App::test_default()
}; };
app.on_tick().await; app.on_tick().await;
@@ -341,10 +349,183 @@ mod tests {
fn test_servarr_config_default() { fn test_servarr_config_default() {
let servarr_config = ServarrConfig::default(); let servarr_config = ServarrConfig::default();
assert_eq!(servarr_config.name, None);
assert_eq!(servarr_config.host, Some("localhost".to_string())); assert_eq!(servarr_config.host, Some("localhost".to_string()));
assert_eq!(servarr_config.port, None); assert_eq!(servarr_config.port, None);
assert_eq!(servarr_config.uri, None); assert_eq!(servarr_config.uri, None);
assert!(servarr_config.api_token.is_empty()); assert_eq!(servarr_config.weight, None);
assert_eq!(servarr_config.api_token, Some(String::new()));
assert_eq!(servarr_config.api_token_file, None);
assert_eq!(servarr_config.ssl_cert_path, None); assert_eq!(servarr_config.ssl_cert_path, None);
} }
#[test]
#[serial]
fn test_deserialize_optional_env_var_is_present() {
unsafe { std::env::set_var("TEST_VAR_DESERIALIZE_OPTION", "localhost") };
let yaml_data = r#"
host: ${TEST_VAR_DESERIALIZE_OPTION}
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.host, Some("localhost".to_string()));
unsafe { std::env::remove_var("TEST_VAR_DESERIALIZE_OPTION") };
}
#[test]
#[serial]
fn test_deserialize_optional_env_var_does_not_overwrite_non_env_value() {
unsafe { std::env::set_var("TEST_VAR_DESERIALIZE_OPTION_NO_OVERWRITE", "localhost") };
let yaml_data = r#"
host: www.example.com
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.host, Some("www.example.com".to_string()));
unsafe { std::env::remove_var("TEST_VAR_DESERIALIZE_OPTION_NO_OVERWRITE") };
}
#[test]
fn test_deserialize_optional_env_var_empty() {
let yaml_data = r#"
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.port, None);
}
#[test]
#[serial]
fn test_deserialize_optional_u16_env_var_is_present() {
unsafe { std::env::set_var("TEST_VAR_DESERIALIZE_OPTION_U16", "1") };
let yaml_data = r#"
port: ${TEST_VAR_DESERIALIZE_OPTION_U16}
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.port, Some(1));
unsafe { std::env::remove_var("TEST_VAR_DESERIALIZE_OPTION_U16") };
}
#[test]
#[serial]
fn test_deserialize_optional_u16_env_var_does_not_overwrite_non_env_value() {
unsafe { std::env::set_var("TEST_VAR_DESERIALIZE_OPTION_U16_UNUSED", "1") };
let yaml_data = r#"
port: 1234
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.port, Some(1234));
unsafe { std::env::remove_var("TEST_VAR_DESERIALIZE_OPTION_U16_UNUSED") };
}
#[test]
fn test_deserialize_optional_u16_env_var_invalid_number() {
let yaml_data = r#"
port: "hi"
api_token: "test123"
"#;
let result: Result<ServarrConfig, _> = serde_yaml::from_str(yaml_data);
assert!(result.is_err());
let err = result.unwrap_err().to_string();
assert!(err.contains("invalid digit found in string"));
}
#[test]
fn test_deserialize_optional_u16_env_var_empty() {
let yaml_data = r#"
api_token: "test123"
"#;
let config: ServarrConfig = serde_yaml::from_str(yaml_data).unwrap();
assert_eq!(config.port, None);
}
#[test]
#[serial]
fn test_interpolate_env_vars() {
unsafe { std::env::set_var("TEST_VAR_INTERPOLATION", "testing") };
let var = interpolate_env_vars("${TEST_VAR_INTERPOLATION}");
assert_str_eq!(var, "testing");
unsafe { std::env::remove_var("TEST_VAR_INTERPOLATION") };
}
#[test]
fn test_interpolate_env_vars_defaults_to_original_string_if_not_in_yaml_interpolation_format() {
let var = interpolate_env_vars("TEST_VAR_INTERPOLATION_NON_YAML");
assert_str_eq!(var, "TEST_VAR_INTERPOLATION_NON_YAML");
}
#[test]
#[serial]
fn test_interpolate_env_vars_scrubs_all_unnecessary_characters() {
unsafe {
std::env::set_var(
"TEST_VAR_INTERPOLATION_UNNECESSARY_CHARACTERS",
r#"""
`"'https://dontdo:this@testing.com/query?test=%20query#results'"` {([\|$!])}
"""#,
)
};
let var = interpolate_env_vars("${TEST_VAR_INTERPOLATION_UNNECESSARY_CHARACTERS}");
assert_str_eq!(
var,
"https://dontdo:this@testing.com/query?test=%20query#results"
);
unsafe { std::env::remove_var("TEST_VAR_INTERPOLATION_UNNECESSARY_CHARACTERS") };
}
#[test]
fn test_interpolate_env_vars_scrubs_all_unnecessary_characters_from_non_environment_variable() {
let var = interpolate_env_vars("https://dontdo:this@testing.com/query?test=%20query#results");
assert_str_eq!(
var,
"https://dontdo:this@testing.com/query?test=%20query#results"
);
}
#[test]
fn test_servarr_config_redacted_debug() {
let name = "Servarr".to_owned();
let host = "localhost".to_owned();
let port = 1234;
let uri = "http://localhost:1234".to_owned();
let weight = 100;
let api_token = "thisisatest".to_owned();
let api_token_file = "/root/.config/api_token".to_owned();
let ssl_cert_path = "/some/path".to_owned();
let expected_str = format!("ServarrConfig {{ name: Some(\"{}\"), host: Some(\"{}\"), port: Some({}), uri: Some(\"{}\"), weight: Some({}), api_token: Some(\"***********\"), api_token_file: Some(\"{}\"), ssl_cert_path: Some(\"{}\") }}",
name, host, port, uri, weight, api_token_file, ssl_cert_path);
let servarr_config = ServarrConfig {
name: Some(name),
host: Some(host),
port: Some(port),
uri: Some(uri),
weight: Some(weight),
api_token: Some(api_token),
api_token_file: Some(api_token_file),
ssl_cert_path: Some(ssl_cert_path),
};
assert_str_eq!(format!("{servarr_config:?}"), expected_str);
}
} }
+61 -1
View File
@@ -44,128 +44,188 @@ generate_keybindings! {
#[derive(Clone, Copy, Eq, PartialEq, Debug)] #[derive(Clone, Copy, Eq, PartialEq, Debug)]
pub struct KeyBinding { pub struct KeyBinding {
pub key: Key, pub key: Key,
pub alt: Option<Key>,
pub desc: &'static str, pub desc: &'static str,
} }
pub const DEFAULT_KEYBINDINGS: KeyBindings = KeyBindings { pub const DEFAULT_KEYBINDINGS: KeyBindings = KeyBindings {
add: KeyBinding { add: KeyBinding {
key: Key::Char('a'), key: Key::Char('a'),
alt: None,
desc: "add", desc: "add",
}, },
up: KeyBinding { up: KeyBinding {
key: Key::Up, key: Key::Up,
alt: Some(Key::Char('k')),
desc: "up", desc: "up",
}, },
down: KeyBinding { down: KeyBinding {
key: Key::Down, key: Key::Down,
alt: Some(Key::Char('j')),
desc: "down", desc: "down",
}, },
left: KeyBinding { left: KeyBinding {
key: Key::Left, key: Key::Left,
alt: Some(Key::Char('h')),
desc: "left", desc: "left",
}, },
right: KeyBinding { right: KeyBinding {
key: Key::Right, key: Key::Right,
alt: Some(Key::Char('l')),
desc: "right", desc: "right",
}, },
backspace: KeyBinding { backspace: KeyBinding {
key: Key::Backspace, key: Key::Backspace,
alt: None,
desc: "backspace", desc: "backspace",
}, },
next_servarr: KeyBinding { next_servarr: KeyBinding {
key: Key::Tab, key: Key::Tab,
alt: None,
desc: "next servarr", desc: "next servarr",
}, },
previous_servarr: KeyBinding { previous_servarr: KeyBinding {
key: Key::BackTab, key: Key::BackTab,
alt: None,
desc: "previous servarr", desc: "previous servarr",
}, },
clear: KeyBinding { clear: KeyBinding {
key: Key::Char('c'), key: Key::Char('c'),
alt: None,
desc: "clear", desc: "clear",
}, },
auto_search: KeyBinding { auto_search: KeyBinding {
key: Key::Char('S'), key: Key::Char('S'),
alt: None,
desc: "auto search", desc: "auto search",
}, },
search: KeyBinding { search: KeyBinding {
key: Key::Char('s'), key: Key::Char('s'),
alt: None,
desc: "search", desc: "search",
}, },
settings: KeyBinding { settings: KeyBinding {
key: Key::Char('S'), key: Key::Char('S'),
alt: None,
desc: "settings", desc: "settings",
}, },
filter: KeyBinding { filter: KeyBinding {
key: Key::Char('f'), key: Key::Char('f'),
alt: None,
desc: "filter", desc: "filter",
}, },
sort: KeyBinding { sort: KeyBinding {
key: Key::Char('o'), key: Key::Char('o'),
alt: None,
desc: "sort", desc: "sort",
}, },
edit: KeyBinding { edit: KeyBinding {
key: Key::Char('e'), key: Key::Char('e'),
alt: None,
desc: "edit", desc: "edit",
}, },
events: KeyBinding { events: KeyBinding {
key: Key::Char('e'), key: Key::Char('e'),
alt: None,
desc: "events", desc: "events",
}, },
logs: KeyBinding { logs: KeyBinding {
key: Key::Char('l'), key: Key::Char('L'),
alt: None,
desc: "logs", desc: "logs",
}, },
tasks: KeyBinding { tasks: KeyBinding {
key: Key::Char('t'), key: Key::Char('t'),
alt: None,
desc: "tasks", desc: "tasks",
}, },
test: KeyBinding { test: KeyBinding {
key: Key::Char('t'), key: Key::Char('t'),
alt: None,
desc: "test", desc: "test",
}, },
test_all: KeyBinding { test_all: KeyBinding {
key: Key::Char('T'), key: Key::Char('T'),
alt: None,
desc: "test all", desc: "test all",
}, },
toggle_monitoring: KeyBinding { toggle_monitoring: KeyBinding {
key: Key::Char('m'), key: Key::Char('m'),
alt: None,
desc: "toggle monitoring", desc: "toggle monitoring",
}, },
refresh: KeyBinding { refresh: KeyBinding {
key: Key::Ctrl('r'), key: Key::Ctrl('r'),
alt: None,
desc: "refresh", desc: "refresh",
}, },
update: KeyBinding { update: KeyBinding {
key: Key::Char('u'), key: Key::Char('u'),
alt: None,
desc: "update", desc: "update",
}, },
home: KeyBinding { home: KeyBinding {
key: Key::Home, key: Key::Home,
alt: None,
desc: "home", desc: "home",
}, },
end: KeyBinding { end: KeyBinding {
key: Key::End, key: Key::End,
alt: None,
desc: "end", desc: "end",
}, },
delete: KeyBinding { delete: KeyBinding {
key: Key::Delete, key: Key::Delete,
alt: None,
desc: "delete", desc: "delete",
}, },
submit: KeyBinding { submit: KeyBinding {
key: Key::Enter, key: Key::Enter,
alt: None,
desc: "submit", desc: "submit",
}, },
confirm: KeyBinding { confirm: KeyBinding {
key: Key::Ctrl('s'), key: Key::Ctrl('s'),
alt: None,
desc: "submit", desc: "submit",
}, },
quit: KeyBinding { quit: KeyBinding {
key: Key::Char('q'), key: Key::Char('q'),
alt: None,
desc: "quit", desc: "quit",
}, },
esc: KeyBinding { esc: KeyBinding {
key: Key::Esc, key: Key::Esc,
alt: None,
desc: "close", desc: "close",
}, },
}; };
#[macro_export]
macro_rules! matches_key {
($binding:ident, $key:expr) => {
$crate::app::key_binding::DEFAULT_KEYBINDINGS.$binding.key == $key
|| ($crate::app::key_binding::DEFAULT_KEYBINDINGS
.$binding
.alt
.is_some()
&& $crate::app::key_binding::DEFAULT_KEYBINDINGS
.$binding
.alt
.unwrap()
== $key)
};
($binding:ident, $key:expr, $ignore_alt_navigation:expr) => {
$crate::app::key_binding::DEFAULT_KEYBINDINGS.$binding.key == $key
|| !$ignore_alt_navigation
&& ($crate::app::key_binding::DEFAULT_KEYBINDINGS
.$binding
.alt
.is_some()
&& $crate::app::key_binding::DEFAULT_KEYBINDINGS
.$binding
.alt
.unwrap()
== $key)
};
}
+1 -1
View File
@@ -23,7 +23,7 @@ mod test {
#[case(DEFAULT_KEYBINDINGS.sort, Key::Char('o'), "sort")] #[case(DEFAULT_KEYBINDINGS.sort, Key::Char('o'), "sort")]
#[case(DEFAULT_KEYBINDINGS.edit, Key::Char('e'), "edit")] #[case(DEFAULT_KEYBINDINGS.edit, Key::Char('e'), "edit")]
#[case(DEFAULT_KEYBINDINGS.events, Key::Char('e'), "events")] #[case(DEFAULT_KEYBINDINGS.events, Key::Char('e'), "events")]
#[case(DEFAULT_KEYBINDINGS.logs, Key::Char('l'), "logs")] #[case(DEFAULT_KEYBINDINGS.logs, Key::Char('L'), "logs")]
#[case(DEFAULT_KEYBINDINGS.tasks, Key::Char('t'), "tasks")] #[case(DEFAULT_KEYBINDINGS.tasks, Key::Char('t'), "tasks")]
#[case(DEFAULT_KEYBINDINGS.test, Key::Char('t'), "test")] #[case(DEFAULT_KEYBINDINGS.test, Key::Char('t'), "test")]
#[case(DEFAULT_KEYBINDINGS.test_all, Key::Char('T'), "test all")] #[case(DEFAULT_KEYBINDINGS.test_all, Key::Char('T'), "test all")]
+216 -58
View File
@@ -1,11 +1,14 @@
use std::process; use anyhow::{anyhow, Error, Result};
use anyhow::{anyhow, Error};
use colored::Colorize; use colored::Colorize;
use itertools::Itertools;
use log::{debug, error}; use log::{debug, error};
use regex::Regex;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use std::{fs, process};
use tokio::sync::mpsc::Sender; use tokio::sync::mpsc::Sender;
use tokio_util::sync::CancellationToken; use tokio_util::sync::CancellationToken;
use veil::Redact;
use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES}; use crate::app::context_clues::{build_context_clue_string, SERVARR_CONTEXT_CLUES};
use crate::cli::Command; use crate::cli::Command;
@@ -38,47 +41,88 @@ pub struct App<'a> {
pub should_refresh: bool, pub should_refresh: bool,
pub should_ignore_quit_key: bool, pub should_ignore_quit_key: bool,
pub cli_mode: bool, pub cli_mode: bool,
pub config: AppConfig,
pub data: Data<'a>, pub data: Data<'a>,
} }
impl<'a> App<'a> { impl App<'_> {
pub fn new( pub fn new(
network_tx: Sender<NetworkEvent>, network_tx: Sender<NetworkEvent>,
config: AppConfig, config: AppConfig,
cancellation_token: CancellationToken, cancellation_token: CancellationToken,
) -> Self { ) -> Self {
let mut server_tabs = Vec::new(); let mut server_tabs = Vec::new();
let help = format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
);
if config.radarr.is_some() { if let Some(radarr_configs) = config.radarr {
server_tabs.push(TabRoute { let mut idx = 0;
title: "Radarr", for radarr_config in radarr_configs {
route: ActiveRadarrBlock::Movies.into(), let name = if let Some(name) = radarr_config.name.clone() {
help: format!( name
"<↑↓> scroll | ←→ change tab | {} ", } else {
build_context_clue_string(&SERVARR_CONTEXT_CLUES) idx += 1;
), format!("Radarr {}", idx)
contextual_help: None, };
});
server_tabs.push(TabRoute {
title: name,
route: ActiveRadarrBlock::Movies.into(),
help: help.clone(),
contextual_help: None,
config: Some(radarr_config),
});
}
} }
if config.sonarr.is_some() { if let Some(sonarr_configs) = config.sonarr {
server_tabs.push(TabRoute { let mut idx = 0;
title: "Sonarr",
route: ActiveSonarrBlock::Series.into(), for sonarr_config in sonarr_configs {
help: format!( let name = if let Some(name) = sonarr_config.name.clone() {
"<↑↓> scroll | ←→ change tab | {} ", name
build_context_clue_string(&SERVARR_CONTEXT_CLUES) } else {
), idx += 1;
contextual_help: None, format!("Sonarr {}", idx)
}); };
server_tabs.push(TabRoute {
title: name,
route: ActiveSonarrBlock::Series.into(),
help: help.clone(),
contextual_help: None,
config: Some(sonarr_config),
});
}
} }
let weight_sorted_tabs = server_tabs
.into_iter()
.sorted_by(|tab1, tab2| {
Ord::cmp(
tab1
.config
.as_ref()
.unwrap()
.weight
.as_ref()
.unwrap_or(&1000),
tab2
.config
.as_ref()
.unwrap()
.weight
.as_ref()
.unwrap_or(&1000),
)
})
.collect();
App { App {
network_tx: Some(network_tx), network_tx: Some(network_tx),
config,
cancellation_token, cancellation_token,
server_tabs: TabState::new(server_tabs), server_tabs: TabState::new(weight_sorted_tabs),
..App::default() ..App::default()
} }
} }
@@ -165,7 +209,7 @@ impl<'a> App<'a> {
} }
} }
impl<'a> Default for App<'a> { impl Default for App<'_> {
fn default() -> Self { fn default() -> Self {
App { App {
navigation_stack: Vec::new(), navigation_stack: Vec::new(),
@@ -173,26 +217,7 @@ impl<'a> Default for App<'a> {
cancellation_token: CancellationToken::new(), cancellation_token: CancellationToken::new(),
error: HorizontallyScrollableText::default(), error: HorizontallyScrollableText::default(),
is_first_render: true, is_first_render: true,
server_tabs: TabState::new(vec![ server_tabs: TabState::new(Vec::new()),
TabRoute {
title: "Radarr",
route: ActiveRadarrBlock::Movies.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
},
TabRoute {
title: "Sonarr",
route: ActiveSonarrBlock::Series.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
},
]),
tick_until_poll: 400, tick_until_poll: 400,
ticks_until_scroll: 4, ticks_until_scroll: 4,
tick_count: 0, tick_count: 0,
@@ -201,12 +226,42 @@ impl<'a> Default for App<'a> {
should_refresh: false, should_refresh: false,
should_ignore_quit_key: false, should_ignore_quit_key: false,
cli_mode: false, cli_mode: false,
config: AppConfig::default(),
data: Data::default(), data: Data::default(),
} }
} }
} }
#[cfg(test)]
impl App<'_> {
pub fn test_default() -> Self {
App {
server_tabs: TabState::new(vec![
TabRoute {
title: "Radarr".to_owned(),
route: ActiveRadarrBlock::Movies.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(ServarrConfig::default()),
},
TabRoute {
title: "Sonarr".to_owned(),
route: ActiveSonarrBlock::Series.into(),
help: format!(
"<↑↓> scroll | ←→ change tab | {} ",
build_context_clue_string(&SERVARR_CONTEXT_CLUES)
),
contextual_help: None,
config: Some(ServarrConfig::default()),
},
]),
..App::default()
}
}
}
#[derive(Default)] #[derive(Default)]
pub struct Data<'a> { pub struct Data<'a> {
pub radarr_data: RadarrData<'a>, pub radarr_data: RadarrData<'a>,
@@ -215,8 +270,9 @@ pub struct Data<'a> {
#[derive(Debug, Deserialize, Serialize, Default, Clone)] #[derive(Debug, Deserialize, Serialize, Default, Clone)]
pub struct AppConfig { pub struct AppConfig {
pub radarr: Option<ServarrConfig>, pub theme: Option<String>,
pub sonarr: Option<ServarrConfig>, pub radarr: Option<Vec<ServarrConfig>>,
pub sonarr: Option<Vec<ServarrConfig>>,
} }
impl AppConfig { impl AppConfig {
@@ -228,12 +284,12 @@ impl AppConfig {
process::exit(1); process::exit(1);
} }
if let Some(radarr_config) = &self.radarr { if let Some(radarr_configs) = &self.radarr {
radarr_config.validate(); radarr_configs.iter().for_each(|config| config.validate());
} }
if let Some(sonarr_config) = &self.sonarr { if let Some(sonarr_configs) = &self.sonarr {
sonarr_config.validate(); sonarr_configs.iter().for_each(|config| config.validate());
} }
} }
@@ -256,14 +312,40 @@ impl AppConfig {
_ => (), _ => (),
} }
} }
pub fn post_process_initialization(&mut self) {
if let Some(radarr_configs) = self.radarr.as_mut() {
for radarr_config in radarr_configs {
radarr_config.post_process_initialization();
}
}
if let Some(sonarr_configs) = self.sonarr.as_mut() {
for sonarr_config in sonarr_configs {
sonarr_config.post_process_initialization();
}
}
}
} }
#[derive(Debug, Deserialize, Serialize, Clone)] #[derive(Redact, Deserialize, Serialize, Clone, PartialEq, Eq)]
pub struct ServarrConfig { pub struct ServarrConfig {
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
pub name: Option<String>,
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
pub host: Option<String>, pub host: Option<String>,
#[serde(default, deserialize_with = "deserialize_u16_env_var")]
pub port: Option<u16>, pub port: Option<u16>,
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
pub uri: Option<String>, pub uri: Option<String>,
pub api_token: String, #[serde(default, deserialize_with = "deserialize_u16_env_var")]
pub weight: Option<u16>,
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
#[redact]
pub api_token: Option<String>,
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
pub api_token_file: Option<String>,
#[serde(default, deserialize_with = "deserialize_optional_env_var")]
pub ssl_cert_path: Option<String>, pub ssl_cert_path: Option<String>,
} }
@@ -273,16 +355,43 @@ impl ServarrConfig {
log_and_print_error("'host' or 'uri' is required for configuration".to_owned()); log_and_print_error("'host' or 'uri' is required for configuration".to_owned());
process::exit(1); process::exit(1);
} }
if self.api_token_file.is_none() && self.api_token.is_none() {
log_and_print_error(
"'api_token' or 'api_token_path' is required for configuration".to_owned(),
);
process::exit(1);
}
}
pub fn post_process_initialization(&mut self) {
if let Some(api_token_file) = self.api_token_file.as_ref() {
if !PathBuf::from(api_token_file).exists() {
log_and_print_error(format!(
"The specified {} API token file does not exist",
api_token_file
));
process::exit(1);
}
let api_token = fs::read_to_string(api_token_file)
.map_err(|e| anyhow!(e))
.unwrap();
self.api_token = Some(api_token.trim().to_owned());
}
} }
} }
impl Default for ServarrConfig { impl Default for ServarrConfig {
fn default() -> Self { fn default() -> Self {
ServarrConfig { ServarrConfig {
name: None,
host: Some("localhost".to_string()), host: Some("localhost".to_string()),
port: None, port: None,
uri: None, uri: None,
api_token: "".to_string(), weight: None,
api_token: Some(String::new()),
api_token_file: None,
ssl_cert_path: None, ssl_cert_path: None,
} }
} }
@@ -292,3 +401,52 @@ pub fn log_and_print_error(error: String) {
error!("{}", error); error!("{}", error);
eprintln!("error: {}", error.red()); eprintln!("error: {}", error.red());
} }
fn deserialize_optional_env_var<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;
match s {
Some(value) => {
let interpolated = interpolate_env_vars(&value);
Ok(Some(interpolated))
}
None => Ok(None),
}
}
fn deserialize_u16_env_var<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error>
where
D: serde::Deserializer<'de>,
{
let s: Option<String> = Option::deserialize(deserializer)?;
match s {
Some(value) => {
let interpolated = interpolate_env_vars(&value);
interpolated
.parse::<u16>()
.map(Some)
.map_err(serde::de::Error::custom)
}
None => Ok(None),
}
}
fn interpolate_env_vars(s: &str) -> String {
let result = s.to_string();
let scrubbing_regex = Regex::new(r#"[\s\{\}!\$^\(\)\[\]\\\|`'"]+"#).unwrap();
let var_regex = Regex::new(r"\$\{(.*?)\}").unwrap();
var_regex
.replace_all(s, |caps: &regex::Captures<'_>| {
if let Some(mat) = caps.get(1) {
if let Ok(value) = std::env::var(mat.as_str()) {
return scrubbing_regex.replace_all(&value, "").to_string();
}
}
scrubbing_regex.replace_all(&result, "").to_string()
})
.to_string()
}
+5 -14
View File
@@ -8,7 +8,7 @@ pub mod radarr_context_clues;
#[path = "radarr_tests.rs"] #[path = "radarr_tests.rs"]
mod radarr_tests; mod radarr_tests;
impl<'a> App<'a> { impl App<'_> {
pub(super) async fn dispatch_by_radarr_block(&mut self, active_radarr_block: &ActiveRadarrBlock) { pub(super) async fn dispatch_by_radarr_block(&mut self, active_radarr_block: &ActiveRadarrBlock) {
match active_radarr_block { match active_radarr_block {
ActiveRadarrBlock::Blocklist => { ActiveRadarrBlock::Blocklist => {
@@ -157,12 +157,9 @@ impl<'a> App<'a> {
async fn check_for_radarr_prompt_action(&mut self) { async fn check_for_radarr_prompt_action(&mut self) {
if self.data.radarr_data.prompt_confirm { if self.data.radarr_data.prompt_confirm {
self.data.radarr_data.prompt_confirm = false; self.data.radarr_data.prompt_confirm = false;
if let Some(radarr_event) = &self.data.radarr_data.prompt_confirm_action { if let Some(radarr_event) = self.data.radarr_data.prompt_confirm_action.take() {
self self.dispatch_network_event(radarr_event.into()).await;
.dispatch_network_event(radarr_event.clone().into())
.await;
self.should_refresh = true; self.should_refresh = true;
self.data.radarr_data.prompt_confirm_action = None;
} }
} }
} }
@@ -231,7 +228,7 @@ impl<'a> App<'a> {
} }
async fn extract_movie_id(&self) -> i64 { async fn extract_movie_id(&self) -> i64 {
self.data.radarr_data.movies.current_selection().clone().id self.data.radarr_data.movies.current_selection().id
} }
async fn extract_movie_search_query(&self) -> String { async fn extract_movie_search_query(&self) -> String {
@@ -246,12 +243,6 @@ impl<'a> App<'a> {
} }
async fn extract_radarr_indexer_id(&self) -> i64 { async fn extract_radarr_indexer_id(&self) -> i64 {
self self.data.radarr_data.indexers.current_selection().id
.data
.radarr_data
.indexers
.current_selection()
.clone()
.id
} }
} }
+9 -9
View File
@@ -467,7 +467,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_dispatch_by_cast_crew_blocks_cast_and_crew_non_empty() { async fn test_dispatch_by_cast_crew_blocks_cast_and_crew_non_empty() {
let mut app = App::default(); let mut app = App::test_default();
for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] { for active_radarr_block in &[ActiveRadarrBlock::Cast, ActiveRadarrBlock::Crew] {
let mut movie_details_modal = MovieDetailsModal::default(); let mut movie_details_modal = MovieDetailsModal::default();
@@ -511,7 +511,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_dispatch_by_manual_search_block_movie_releases_non_empty() { async fn test_dispatch_by_manual_search_block_movie_releases_non_empty() {
let mut app = App::default(); let mut app = App::test_default();
let mut movie_details_modal = MovieDetailsModal::default(); let mut movie_details_modal = MovieDetailsModal::default();
movie_details_modal movie_details_modal
.movie_releases .movie_releases
@@ -531,7 +531,7 @@ mod tests {
async fn test_dispatch_by_manual_search_block_is_loading() { async fn test_dispatch_by_manual_search_block_is_loading() {
let mut app = App { let mut app = App {
is_loading: true, is_loading: true,
..App::default() ..App::test_default()
}; };
app app
@@ -545,7 +545,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_check_for_radarr_prompt_action_no_prompt_confirm() { async fn test_check_for_radarr_prompt_action_no_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.prompt_confirm = false; app.data.radarr_data.prompt_confirm = false;
app.check_for_radarr_prompt_action().await; app.check_for_radarr_prompt_action().await;
@@ -729,7 +729,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_populate_movie_collection_table_unfiltered() { async fn test_populate_movie_collection_table_unfiltered() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.collections.set_items(vec![Collection { app.data.radarr_data.collections.set_items(vec![Collection {
movies: Some(vec![CollectionMovie::default()]), movies: Some(vec![CollectionMovie::default()]),
..Collection::default() ..Collection::default()
@@ -742,7 +742,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_populate_movie_collection_table_filtered() { async fn test_populate_movie_collection_table_filtered() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -759,7 +759,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_extract_movie_id() { async fn test_extract_movie_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.movies.set_items(vec![Movie { app.data.radarr_data.movies.set_items(vec![Movie {
id: 1, id: 1,
..Movie::default() ..Movie::default()
@@ -770,7 +770,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_extract_radarr_indexer_id() { async fn test_extract_radarr_indexer_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexers.set_items(vec![Indexer { app.data.radarr_data.indexers.set_items(vec![Indexer {
id: 1, id: 1,
..Indexer::default() ..Indexer::default()
@@ -785,7 +785,7 @@ mod tests {
network_tx: Some(sync_network_tx), network_tx: Some(sync_network_tx),
tick_count: 1, tick_count: 1,
is_first_render: false, is_first_render: false,
..App::default() ..App::test_default()
}; };
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
+3 -6
View File
@@ -11,7 +11,7 @@ pub mod sonarr_context_clues;
#[path = "sonarr_tests.rs"] #[path = "sonarr_tests.rs"]
mod sonarr_tests; mod sonarr_tests;
impl<'a> App<'a> { impl App<'_> {
pub(super) async fn dispatch_by_sonarr_block(&mut self, active_sonarr_block: &ActiveSonarrBlock) { pub(super) async fn dispatch_by_sonarr_block(&mut self, active_sonarr_block: &ActiveSonarrBlock) {
match active_sonarr_block { match active_sonarr_block {
ActiveSonarrBlock::Series => { ActiveSonarrBlock::Series => {
@@ -187,12 +187,9 @@ impl<'a> App<'a> {
async fn check_for_sonarr_prompt_action(&mut self) { async fn check_for_sonarr_prompt_action(&mut self) {
if self.data.sonarr_data.prompt_confirm { if self.data.sonarr_data.prompt_confirm {
self.data.sonarr_data.prompt_confirm = false; self.data.sonarr_data.prompt_confirm = false;
if let Some(sonarr_event) = &self.data.sonarr_data.prompt_confirm_action { if let Some(sonarr_event) = self.data.sonarr_data.prompt_confirm_action.take() {
self self.dispatch_network_event(sonarr_event.into()).await;
.dispatch_network_event(sonarr_event.clone().into())
.await;
self.should_refresh = true; self.should_refresh = true;
self.data.sonarr_data.prompt_confirm_action = None;
} }
} }
} }
+15 -15
View File
@@ -185,7 +185,7 @@ mod tests {
async fn test_dispatch_by_manual_season_search_block_is_loading() { async fn test_dispatch_by_manual_season_search_block_is_loading() {
let mut app = App { let mut app = App {
is_loading: true, is_loading: true,
..App::default() ..App::test_default()
}; };
app app
@@ -199,7 +199,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_dispatch_by_manual_season_search_block_season_releases_non_empty() { async fn test_dispatch_by_manual_season_search_block_season_releases_non_empty() {
let mut app = App::default(); let mut app = App::test_default();
let mut season_details_modal = SeasonDetailsModal::default(); let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal season_details_modal
.season_releases .season_releases
@@ -304,7 +304,7 @@ mod tests {
async fn test_dispatch_by_manual_episode_search_block_is_loading() { async fn test_dispatch_by_manual_episode_search_block_is_loading() {
let mut app = App { let mut app = App {
is_loading: true, is_loading: true,
..App::default() ..App::test_default()
}; };
app app
@@ -318,7 +318,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_dispatch_by_manual_episode_search_block_episode_releases_non_empty() { async fn test_dispatch_by_manual_episode_search_block_episode_releases_non_empty() {
let mut app = App::default(); let mut app = App::test_default();
let mut episode_details_modal = EpisodeDetailsModal::default(); let mut episode_details_modal = EpisodeDetailsModal::default();
episode_details_modal episode_details_modal
.episode_releases .episode_releases
@@ -554,7 +554,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_check_for_sonarr_prompt_action_no_prompt_confirm() { async fn test_check_for_sonarr_prompt_action_no_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.prompt_confirm = false; app.data.sonarr_data.prompt_confirm = false;
app.check_for_sonarr_prompt_action().await; app.check_for_sonarr_prompt_action().await;
@@ -750,7 +750,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_populate_seasons_table_unfiltered() { async fn test_populate_seasons_table_unfiltered() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.series.set_items(vec![Series { app.data.sonarr_data.series.set_items(vec![Series {
seasons: Some(vec![Season::default()]), seasons: Some(vec![Season::default()]),
..Series::default() ..Series::default()
@@ -770,7 +770,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_populate_seasons_table_filtered() { async fn test_populate_seasons_table_filtered() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.series.set_filtered_items(vec![Series { app.data.sonarr_data.series.set_filtered_items(vec![Series {
seasons: Some(vec![Season::default()]), seasons: Some(vec![Season::default()]),
..Series::default() ..Series::default()
@@ -790,7 +790,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_extract_episode_id() { async fn test_extract_episode_id() {
let mut app = App::default(); let mut app = App::test_default();
let mut season_details_modal = SeasonDetailsModal::default(); let mut season_details_modal = SeasonDetailsModal::default();
season_details_modal.episodes.set_items(vec![Episode { season_details_modal.episodes.set_items(vec![Episode {
id: 1, id: 1,
@@ -804,14 +804,14 @@ mod tests {
#[tokio::test] #[tokio::test]
#[should_panic(expected = "Season details have not been loaded")] #[should_panic(expected = "Season details have not been loaded")]
async fn test_extract_episode_id_requires_season_details_modal_to_be_some() { async fn test_extract_episode_id_requires_season_details_modal_to_be_some() {
let app = App::default(); let app = App::test_default();
assert_eq!(app.extract_episode_id().await, 0); assert_eq!(app.extract_episode_id().await, 0);
} }
#[tokio::test] #[tokio::test]
async fn test_extract_series_id() { async fn test_extract_series_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.series.set_items(vec![Series { app.data.sonarr_data.series.set_items(vec![Series {
id: 1, id: 1,
..Series::default() ..Series::default()
@@ -822,7 +822,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_extract_series_id_season_number_tuple() { async fn test_extract_series_id_season_number_tuple() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.series.set_items(vec![Series { app.data.sonarr_data.series.set_items(vec![Series {
id: 1, id: 1,
..Series::default() ..Series::default()
@@ -837,7 +837,7 @@ mod tests {
#[tokio::test] #[tokio::test]
async fn test_extract_add_new_series_search_query() { async fn test_extract_add_new_series_search_query() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.add_series_search = Some("test search".into()); app.data.sonarr_data.add_series_search = Some("test search".into());
assert_str_eq!( assert_str_eq!(
@@ -849,14 +849,14 @@ mod tests {
#[tokio::test] #[tokio::test]
#[should_panic(expected = "Add series search is empty")] #[should_panic(expected = "Add series search is empty")]
async fn test_extract_add_new_series_search_query_panics_when_the_query_is_not_set() { async fn test_extract_add_new_series_search_query_panics_when_the_query_is_not_set() {
let app = App::default(); let app = App::test_default();
app.extract_add_new_series_search_query().await; app.extract_add_new_series_search_query().await;
} }
#[tokio::test] #[tokio::test]
async fn test_extract_sonarr_indexer_id() { async fn test_extract_sonarr_indexer_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.indexers.set_items(vec![Indexer { app.data.sonarr_data.indexers.set_items(vec![Indexer {
id: 1, id: 1,
..Indexer::default() ..Indexer::default()
@@ -871,7 +871,7 @@ mod tests {
network_tx: Some(sync_network_tx), network_tx: Some(sync_network_tx),
tick_count: 1, tick_count: 1,
is_first_render: false, is_first_render: false,
..App::default() ..App::test_default()
}; };
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
+2 -2
View File
@@ -136,7 +136,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let clear_blocklist_command = RadarrCommand::ClearBlocklist.into(); let clear_blocklist_command = RadarrCommand::ClearBlocklist.into();
let result = handle_command(&app_arc, clear_blocklist_command, &mut mock_network).await; let result = handle_command(&app_arc, clear_blocklist_command, &mut mock_network).await;
@@ -167,7 +167,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let clear_blocklist_command = SonarrCommand::ClearBlocklist.into(); let clear_blocklist_command = SonarrCommand::ClearBlocklist.into();
let result = handle_command(&app_arc, clear_blocklist_command, &mut mock_network).await; let result = handle_command(&app_arc, clear_blocklist_command, &mut mock_network).await;
+3 -3
View File
@@ -400,7 +400,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_movie_command = RadarrAddCommand::Movie { let add_movie_command = RadarrAddCommand::Movie {
tmdb_id: 1, tmdb_id: 1,
root_folder_path: "/test".to_owned(), root_folder_path: "/test".to_owned(),
@@ -437,7 +437,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_root_folder_command = RadarrAddCommand::RootFolder { let add_root_folder_command = RadarrAddCommand::RootFolder {
root_folder_path: expected_root_folder_path, root_folder_path: expected_root_folder_path,
}; };
@@ -465,7 +465,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_tag_command = RadarrAddCommand::Tag { let add_tag_command = RadarrAddCommand::Tag {
name: expected_tag_name, name: expected_tag_name,
}; };
@@ -276,7 +276,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_blocklist_item_command = RadarrDeleteCommand::BlocklistItem { let delete_blocklist_item_command = RadarrDeleteCommand::BlocklistItem {
blocklist_item_id: 1, blocklist_item_id: 1,
}; };
@@ -307,7 +307,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_download_command = RadarrDeleteCommand::Download { download_id: 1 }; let delete_download_command = RadarrDeleteCommand::Download { download_id: 1 };
let result = let result =
@@ -333,7 +333,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_indexer_command = RadarrDeleteCommand::Indexer { indexer_id: 1 }; let delete_indexer_command = RadarrDeleteCommand::Indexer { indexer_id: 1 };
let result = let result =
@@ -363,7 +363,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_movie_command = RadarrDeleteCommand::Movie { let delete_movie_command = RadarrDeleteCommand::Movie {
movie_id: 1, movie_id: 1,
delete_files_from_disk: true, delete_files_from_disk: true,
@@ -393,7 +393,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_root_folder_command = RadarrDeleteCommand::RootFolder { root_folder_id: 1 }; let delete_root_folder_command = RadarrDeleteCommand::RootFolder { root_folder_id: 1 };
let result = let result =
@@ -419,7 +419,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_tag_command = RadarrDeleteCommand::Tag { tag_id: 1 }; let delete_tag_command = RadarrDeleteCommand::Tag { tag_id: 1 };
let result = let result =
+1 -7
View File
@@ -379,13 +379,7 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrEditCommand> for RadarrEditCommandH
rss_sync_interval: rss_sync_interval rss_sync_interval: rss_sync_interval
.unwrap_or(previous_indexer_settings.rss_sync_interval), .unwrap_or(previous_indexer_settings.rss_sync_interval),
whitelisted_hardcoded_subs: whitelisted_subtitle_tags whitelisted_hardcoded_subs: whitelisted_subtitle_tags
.clone() .unwrap_or(previous_indexer_settings.whitelisted_hardcoded_subs.text)
.unwrap_or_else(|| {
previous_indexer_settings
.whitelisted_hardcoded_subs
.text
.clone()
})
.into(), .into(),
}; };
self self
+12 -12
View File
@@ -865,7 +865,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings { let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings {
allow_hardcoded_subs: true, allow_hardcoded_subs: true,
disable_allow_hardcoded_subs: false, disable_allow_hardcoded_subs: false,
@@ -936,7 +936,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings { let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings {
allow_hardcoded_subs: false, allow_hardcoded_subs: false,
disable_allow_hardcoded_subs: true, disable_allow_hardcoded_subs: true,
@@ -1008,7 +1008,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings { let edit_all_indexer_settings_command = RadarrEditCommand::AllIndexerSettings {
allow_hardcoded_subs: false, allow_hardcoded_subs: false,
disable_allow_hardcoded_subs: false, disable_allow_hardcoded_subs: false,
@@ -1055,7 +1055,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_collection_command = RadarrEditCommand::Collection { let edit_collection_command = RadarrEditCommand::Collection {
collection_id: 1, collection_id: 1,
enable_monitoring: true, enable_monitoring: true,
@@ -1097,7 +1097,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_collection_command = RadarrEditCommand::Collection { let edit_collection_command = RadarrEditCommand::Collection {
collection_id: 1, collection_id: 1,
enable_monitoring: false, enable_monitoring: false,
@@ -1139,7 +1139,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_collection_command = RadarrEditCommand::Collection { let edit_collection_command = RadarrEditCommand::Collection {
collection_id: 1, collection_id: 1,
enable_monitoring: false, enable_monitoring: false,
@@ -1187,7 +1187,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_indexer_command = RadarrEditCommand::Indexer { let edit_indexer_command = RadarrEditCommand::Indexer {
indexer_id: 1, indexer_id: 1,
name: Some("Test".to_owned()), name: Some("Test".to_owned()),
@@ -1241,7 +1241,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_indexer_command = RadarrEditCommand::Indexer { let edit_indexer_command = RadarrEditCommand::Indexer {
indexer_id: 1, indexer_id: 1,
name: Some("Test".to_owned()), name: Some("Test".to_owned()),
@@ -1295,7 +1295,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_indexer_command = RadarrEditCommand::Indexer { let edit_indexer_command = RadarrEditCommand::Indexer {
indexer_id: 1, indexer_id: 1,
name: Some("Test".to_owned()), name: Some("Test".to_owned()),
@@ -1345,7 +1345,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_movie_command = RadarrEditCommand::Movie { let edit_movie_command = RadarrEditCommand::Movie {
movie_id: 1, movie_id: 1,
enable_monitoring: true, enable_monitoring: true,
@@ -1388,7 +1388,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_movie_command = RadarrEditCommand::Movie { let edit_movie_command = RadarrEditCommand::Movie {
movie_id: 1, movie_id: 1,
enable_monitoring: false, enable_monitoring: false,
@@ -1431,7 +1431,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_movie_command = RadarrEditCommand::Movie { let edit_movie_command = RadarrEditCommand::Movie {
movie_id: 1, movie_id: 1,
enable_monitoring: false, enable_monitoring: false,
+6 -6
View File
@@ -138,7 +138,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_all_indexer_settings_command = RadarrGetCommand::AllIndexerSettings; let get_all_indexer_settings_command = RadarrGetCommand::AllIndexerSettings;
let result = RadarrGetCommandHandler::with( let result = RadarrGetCommandHandler::with(
@@ -164,7 +164,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_host_config_command = RadarrGetCommand::HostConfig; let get_host_config_command = RadarrGetCommand::HostConfig;
let result = let result =
@@ -190,7 +190,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_movie_details_command = RadarrGetCommand::MovieDetails { movie_id: 1 }; let get_movie_details_command = RadarrGetCommand::MovieDetails { movie_id: 1 };
let result = let result =
@@ -216,7 +216,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_movie_history_command = RadarrGetCommand::MovieHistory { movie_id: 1 }; let get_movie_history_command = RadarrGetCommand::MovieHistory { movie_id: 1 };
let result = let result =
@@ -239,7 +239,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_security_config_command = RadarrGetCommand::SecurityConfig; let get_security_config_command = RadarrGetCommand::SecurityConfig;
let result = let result =
@@ -262,7 +262,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_system_status_command = RadarrGetCommand::SystemStatus; let get_system_status_command = RadarrGetCommand::SystemStatus;
let result = let result =
+2 -2
View File
@@ -135,9 +135,9 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, RadarrListCommand> for RadarrListCommandH
.await?; .await?;
if output_in_log_format { if output_in_log_format {
let log_lines = self.app.lock().await.data.radarr_data.logs.items.clone(); let log_lines = &self.app.lock().await.data.radarr_data.logs.items;
serde_json::to_string_pretty(&log_lines)? serde_json::to_string_pretty(log_lines)?
} else { } else {
serde_json::to_string_pretty(&logs)? serde_json::to_string_pretty(&logs)?
} }
+3 -3
View File
@@ -147,7 +147,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let result = RadarrListCommandHandler::with(&app_arc, list_command, &mut mock_network) let result = RadarrListCommandHandler::with(&app_arc, list_command, &mut mock_network)
.handle() .handle()
@@ -171,7 +171,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_movie_credits_command = RadarrListCommand::MovieCredits { movie_id: 1 }; let list_movie_credits_command = RadarrListCommand::MovieCredits { movie_id: 1 };
let result = let result =
@@ -197,7 +197,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_logs_command = RadarrListCommand::Logs { let list_logs_command = RadarrListCommand::Logs {
events: 1000, events: 1000,
output_in_log_format: false, output_in_log_format: false,
+14 -14
View File
@@ -292,7 +292,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let clear_blocklist_command = RadarrCommand::ClearBlocklist; let clear_blocklist_command = RadarrCommand::ClearBlocklist;
let result = RadarrCliHandler::with(&app_arc, clear_blocklist_command, &mut mock_network) let result = RadarrCliHandler::with(&app_arc, clear_blocklist_command, &mut mock_network)
@@ -321,7 +321,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let download_release_command = RadarrCommand::DownloadRelease { let download_release_command = RadarrCommand::DownloadRelease {
guid: "guid".to_owned(), guid: "guid".to_owned(),
indexer_id: 1, indexer_id: 1,
@@ -350,7 +350,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let manual_search_command = RadarrCommand::ManualSearch { movie_id: 1 }; let manual_search_command = RadarrCommand::ManualSearch { movie_id: 1 };
let result = RadarrCliHandler::with(&app_arc, manual_search_command, &mut mock_network) let result = RadarrCliHandler::with(&app_arc, manual_search_command, &mut mock_network)
@@ -375,7 +375,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let search_new_movie_command = RadarrCommand::SearchNewMovie { let search_new_movie_command = RadarrCommand::SearchNewMovie {
query: "halo".to_owned(), query: "halo".to_owned(),
}; };
@@ -402,7 +402,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let start_task_command = RadarrCommand::StartTask { let start_task_command = RadarrCommand::StartTask {
task_name: RadarrTaskName::ApplicationCheckUpdate, task_name: RadarrTaskName::ApplicationCheckUpdate,
}; };
@@ -429,7 +429,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let test_indexer_command = RadarrCommand::TestIndexer { indexer_id: 1 }; let test_indexer_command = RadarrCommand::TestIndexer { indexer_id: 1 };
let result = RadarrCliHandler::with(&app_arc, test_indexer_command, &mut mock_network) let result = RadarrCliHandler::with(&app_arc, test_indexer_command, &mut mock_network)
@@ -451,7 +451,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let test_all_indexers_command = RadarrCommand::TestAllIndexers; let test_all_indexers_command = RadarrCommand::TestAllIndexers;
let result = RadarrCliHandler::with(&app_arc, test_all_indexers_command, &mut mock_network) let result = RadarrCliHandler::with(&app_arc, test_all_indexers_command, &mut mock_network)
@@ -476,7 +476,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let trigger_automatic_search_command = RadarrCommand::TriggerAutomaticSearch { movie_id: 1 }; let trigger_automatic_search_command = RadarrCommand::TriggerAutomaticSearch { movie_id: 1 };
let result = RadarrCliHandler::with( let result = RadarrCliHandler::with(
@@ -505,7 +505,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_tag_command = RadarrCommand::Add(RadarrAddCommand::Tag { let add_tag_command = RadarrCommand::Add(RadarrAddCommand::Tag {
name: expected_tag_name, name: expected_tag_name,
}); });
@@ -532,7 +532,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_blocklist_item_command = let delete_blocklist_item_command =
RadarrCommand::Delete(RadarrDeleteCommand::BlocklistItem { RadarrCommand::Delete(RadarrDeleteCommand::BlocklistItem {
blocklist_item_id: 1, blocklist_item_id: 1,
@@ -592,7 +592,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = let edit_all_indexer_settings_command =
RadarrCommand::Edit(RadarrEditCommand::AllIndexerSettings { RadarrCommand::Edit(RadarrEditCommand::AllIndexerSettings {
allow_hardcoded_subs: true, allow_hardcoded_subs: true,
@@ -632,7 +632,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_all_indexer_settings_command = let get_all_indexer_settings_command =
RadarrCommand::Get(RadarrGetCommand::AllIndexerSettings); RadarrCommand::Get(RadarrGetCommand::AllIndexerSettings);
@@ -662,7 +662,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_movie_credits_command = let list_movie_credits_command =
RadarrCommand::List(RadarrListCommand::MovieCredits { movie_id: 1 }); RadarrCommand::List(RadarrListCommand::MovieCredits { movie_id: 1 });
@@ -688,7 +688,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let refresh_movie_command = let refresh_movie_command =
RadarrCommand::Refresh(RadarrRefreshCommand::Movie { movie_id: 1 }); RadarrCommand::Refresh(RadarrRefreshCommand::Movie { movie_id: 1 });
@@ -96,7 +96,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let result = RadarrRefreshCommandHandler::with(&app_arc, refresh_command, &mut mock_network) let result = RadarrRefreshCommandHandler::with(&app_arc, refresh_command, &mut mock_network)
.handle() .handle()
@@ -120,7 +120,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let refresh_movie_command = RadarrRefreshCommand::Movie { movie_id: 1 }; let refresh_movie_command = RadarrRefreshCommand::Movie { movie_id: 1 };
let result = let result =
+3 -3
View File
@@ -491,7 +491,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_root_folder_command = SonarrAddCommand::RootFolder { let add_root_folder_command = SonarrAddCommand::RootFolder {
root_folder_path: expected_root_folder_path, root_folder_path: expected_root_folder_path,
}; };
@@ -535,7 +535,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_series_command = SonarrAddCommand::Series { let add_series_command = SonarrAddCommand::Series {
tvdb_id: 1, tvdb_id: 1,
title: "test".to_owned(), title: "test".to_owned(),
@@ -572,7 +572,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_tag_command = SonarrAddCommand::Tag { let add_tag_command = SonarrAddCommand::Tag {
name: expected_tag_name, name: expected_tag_name,
}; };
@@ -309,7 +309,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_blocklist_item_command = SonarrDeleteCommand::BlocklistItem { let delete_blocklist_item_command = SonarrDeleteCommand::BlocklistItem {
blocklist_item_id: 1, blocklist_item_id: 1,
}; };
@@ -340,7 +340,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_download_command = SonarrDeleteCommand::Download { download_id: 1 }; let delete_download_command = SonarrDeleteCommand::Download { download_id: 1 };
let result = let result =
@@ -366,7 +366,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_episode_file_command = SonarrDeleteCommand::EpisodeFile { episode_file_id: 1 }; let delete_episode_file_command = SonarrDeleteCommand::EpisodeFile { episode_file_id: 1 };
let result = let result =
@@ -392,7 +392,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_indexer_command = SonarrDeleteCommand::Indexer { indexer_id: 1 }; let delete_indexer_command = SonarrDeleteCommand::Indexer { indexer_id: 1 };
let result = let result =
@@ -418,7 +418,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_root_folder_command = SonarrDeleteCommand::RootFolder { root_folder_id: 1 }; let delete_root_folder_command = SonarrDeleteCommand::RootFolder { root_folder_id: 1 };
let result = let result =
@@ -448,7 +448,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_series_command = SonarrDeleteCommand::Series { let delete_series_command = SonarrDeleteCommand::Series {
series_id: 1, series_id: 1,
delete_files_from_disk: true, delete_files_from_disk: true,
@@ -478,7 +478,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_tag_command = SonarrDeleteCommand::Tag { tag_id: 1 }; let delete_tag_command = SonarrDeleteCommand::Tag { tag_id: 1 };
let result = let result =
@@ -333,7 +333,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let download_release_command = SonarrDownloadCommand::Series { let download_release_command = SonarrDownloadCommand::Series {
guid: "guid".to_owned(), guid: "guid".to_owned(),
indexer_id: 1, indexer_id: 1,
@@ -369,7 +369,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let download_release_command = SonarrDownloadCommand::Season { let download_release_command = SonarrDownloadCommand::Season {
guid: "guid".to_owned(), guid: "guid".to_owned(),
indexer_id: 1, indexer_id: 1,
@@ -405,7 +405,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let download_release_command = SonarrDownloadCommand::Episode { let download_release_command = SonarrDownloadCommand::Episode {
guid: "guid".to_owned(), guid: "guid".to_owned(),
indexer_id: 1, indexer_id: 1,
+5 -5
View File
@@ -658,7 +658,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = SonarrEditCommand::AllIndexerSettings { let edit_all_indexer_settings_command = SonarrEditCommand::AllIndexerSettings {
maximum_size: Some(1), maximum_size: Some(1),
minimum_age: Some(1), minimum_age: Some(1),
@@ -705,7 +705,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_indexer_command = SonarrEditCommand::Indexer { let edit_indexer_command = SonarrEditCommand::Indexer {
indexer_id: 1, indexer_id: 1,
name: Some("Test".to_owned()), name: Some("Test".to_owned()),
@@ -757,7 +757,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_series_command = SonarrEditCommand::Series { let edit_series_command = SonarrEditCommand::Series {
series_id: 1, series_id: 1,
enable_monitoring: true, enable_monitoring: true,
@@ -805,7 +805,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_series_command = SonarrEditCommand::Series { let edit_series_command = SonarrEditCommand::Series {
series_id: 1, series_id: 1,
enable_monitoring: false, enable_monitoring: false,
@@ -853,7 +853,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_series_command = SonarrEditCommand::Series { let edit_series_command = SonarrEditCommand::Series {
series_id: 1, series_id: 1,
enable_monitoring: false, enable_monitoring: false,
+6 -6
View File
@@ -139,7 +139,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_all_indexer_settings_command = SonarrGetCommand::AllIndexerSettings; let get_all_indexer_settings_command = SonarrGetCommand::AllIndexerSettings;
let result = SonarrGetCommandHandler::with( let result = SonarrGetCommandHandler::with(
@@ -168,7 +168,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_episode_details_command = SonarrGetCommand::EpisodeDetails { episode_id: 1 }; let get_episode_details_command = SonarrGetCommand::EpisodeDetails { episode_id: 1 };
let result = let result =
@@ -191,7 +191,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_host_config_command = SonarrGetCommand::HostConfig; let get_host_config_command = SonarrGetCommand::HostConfig;
let result = let result =
@@ -214,7 +214,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_security_config_command = SonarrGetCommand::SecurityConfig; let get_security_config_command = SonarrGetCommand::SecurityConfig;
let result = let result =
@@ -240,7 +240,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_series_details_command = SonarrGetCommand::SeriesDetails { series_id: 1 }; let get_series_details_command = SonarrGetCommand::SeriesDetails { series_id: 1 };
let result = let result =
@@ -263,7 +263,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_system_status_command = SonarrGetCommand::SystemStatus; let get_system_status_command = SonarrGetCommand::SystemStatus;
let result = let result =
+2 -2
View File
@@ -212,9 +212,9 @@ impl<'a, 'b> CliCommandHandler<'a, 'b, SonarrListCommand> for SonarrListCommandH
.await?; .await?;
if output_in_log_format { if output_in_log_format {
let log_lines = self.app.lock().await.data.sonarr_data.logs.items.clone(); let log_lines = &self.app.lock().await.data.sonarr_data.logs.items;
serde_json::to_string_pretty(&log_lines)? serde_json::to_string_pretty(log_lines)?
} else { } else {
serde_json::to_string_pretty(&logs)? serde_json::to_string_pretty(&logs)?
} }
+8 -8
View File
@@ -313,7 +313,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let result = SonarrListCommandHandler::with(&app_arc, list_command, &mut mock_network) let result = SonarrListCommandHandler::with(&app_arc, list_command, &mut mock_network)
.handle() .handle()
@@ -337,7 +337,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_episodes_command = SonarrListCommand::Episodes { series_id: 1 }; let list_episodes_command = SonarrListCommand::Episodes { series_id: 1 };
let result = let result =
@@ -363,7 +363,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_episode_files_command = SonarrListCommand::EpisodeFiles { series_id: 1 }; let list_episode_files_command = SonarrListCommand::EpisodeFiles { series_id: 1 };
let result = let result =
@@ -389,7 +389,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_history_command = SonarrListCommand::History { events: 1000 }; let list_history_command = SonarrListCommand::History { events: 1000 };
let result = let result =
@@ -415,7 +415,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_logs_command = SonarrListCommand::Logs { let list_logs_command = SonarrListCommand::Logs {
events: 1000, events: 1000,
output_in_log_format: false, output_in_log_format: false,
@@ -443,7 +443,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_series_history_command = SonarrListCommand::SeriesHistory { series_id: 1 }; let list_series_history_command = SonarrListCommand::SeriesHistory { series_id: 1 };
let result = let result =
@@ -469,7 +469,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_episode_history_command = SonarrListCommand::EpisodeHistory { episode_id: 1 }; let list_episode_history_command = SonarrListCommand::EpisodeHistory { episode_id: 1 };
let result = let result =
@@ -496,7 +496,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_season_history_command = SonarrListCommand::SeasonHistory { let list_season_history_command = SonarrListCommand::SeasonHistory {
series_id: 1, series_id: 1,
season_number: 1, season_number: 1,
@@ -138,7 +138,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let manual_episode_search_command = SonarrManualSearchCommand::Episode { episode_id: 1 }; let manual_episode_search_command = SonarrManualSearchCommand::Episode { episode_id: 1 };
let result = SonarrManualSearchCommandHandler::with( let result = SonarrManualSearchCommandHandler::with(
@@ -168,7 +168,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let manual_season_search_command = SonarrManualSearchCommand::Season { let manual_season_search_command = SonarrManualSearchCommand::Season {
series_id: 1, series_id: 1,
season_number: 1, season_number: 1,
@@ -103,7 +103,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let result = SonarrRefreshCommandHandler::with(&app_arc, refresh_command, &mut mock_network) let result = SonarrRefreshCommandHandler::with(&app_arc, refresh_command, &mut mock_network)
.handle() .handle()
@@ -127,7 +127,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let refresh_series_command = SonarrRefreshCommand::Series { series_id: 1 }; let refresh_series_command = SonarrRefreshCommand::Series { series_id: 1 };
let result = let result =
+17 -17
View File
@@ -272,7 +272,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let claer_blocklist_command = SonarrCommand::ClearBlocklist; let claer_blocklist_command = SonarrCommand::ClearBlocklist;
let result = SonarrCliHandler::with(&app_arc, claer_blocklist_command, &mut mock_network) let result = SonarrCliHandler::with(&app_arc, claer_blocklist_command, &mut mock_network)
@@ -297,7 +297,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let mark_history_item_as_failed_command = let mark_history_item_as_failed_command =
SonarrCommand::MarkHistoryItemAsFailed { history_item_id: 1 }; SonarrCommand::MarkHistoryItemAsFailed { history_item_id: 1 };
@@ -327,7 +327,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let add_tag_command = SonarrCommand::Add(SonarrAddCommand::Tag { let add_tag_command = SonarrCommand::Add(SonarrAddCommand::Tag {
name: expected_tag_name, name: expected_tag_name,
}); });
@@ -354,7 +354,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let delete_blocklist_item_command = let delete_blocklist_item_command =
SonarrCommand::Delete(SonarrDeleteCommand::BlocklistItem { SonarrCommand::Delete(SonarrDeleteCommand::BlocklistItem {
blocklist_item_id: 1, blocklist_item_id: 1,
@@ -388,7 +388,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let download_series_release_command = let download_series_release_command =
SonarrCommand::Download(SonarrDownloadCommand::Series { SonarrCommand::Download(SonarrDownloadCommand::Series {
guid: "1234".to_owned(), guid: "1234".to_owned(),
@@ -442,7 +442,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let edit_all_indexer_settings_command = let edit_all_indexer_settings_command =
SonarrCommand::Edit(SonarrEditCommand::AllIndexerSettings { SonarrCommand::Edit(SonarrEditCommand::AllIndexerSettings {
maximum_size: Some(1), maximum_size: Some(1),
@@ -478,7 +478,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let manual_episode_search_command = let manual_episode_search_command =
SonarrCommand::ManualSearch(SonarrManualSearchCommand::Episode { episode_id: 1 }); SonarrCommand::ManualSearch(SonarrManualSearchCommand::Episode { episode_id: 1 });
@@ -506,7 +506,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let manual_episode_search_command = let manual_episode_search_command =
SonarrCommand::TriggerAutomaticSearch(SonarrTriggerAutomaticSearchCommand::Episode { SonarrCommand::TriggerAutomaticSearch(SonarrTriggerAutomaticSearchCommand::Episode {
episode_id: 1, episode_id: 1,
@@ -532,7 +532,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let get_system_status_command = SonarrCommand::Get(SonarrGetCommand::SystemStatus); let get_system_status_command = SonarrCommand::Get(SonarrGetCommand::SystemStatus);
let result = SonarrCliHandler::with(&app_arc, get_system_status_command, &mut mock_network) let result = SonarrCliHandler::with(&app_arc, get_system_status_command, &mut mock_network)
@@ -554,7 +554,7 @@ mod tests {
Series::default(), Series::default(),
]))) ])))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let list_series_command = SonarrCommand::List(SonarrListCommand::Series); let list_series_command = SonarrCommand::List(SonarrListCommand::Series);
let result = SonarrCliHandler::with(&app_arc, list_series_command, &mut mock_network) let result = SonarrCliHandler::with(&app_arc, list_series_command, &mut mock_network)
@@ -579,7 +579,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let refresh_series_command = let refresh_series_command =
SonarrCommand::Refresh(SonarrRefreshCommand::Series { series_id: 1 }); SonarrCommand::Refresh(SonarrRefreshCommand::Series { series_id: 1 });
@@ -605,7 +605,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let search_new_series_command = SonarrCommand::SearchNewSeries { let search_new_series_command = SonarrCommand::SearchNewSeries {
query: "halo".to_owned(), query: "halo".to_owned(),
}; };
@@ -632,7 +632,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let start_task_command = SonarrCommand::StartTask { let start_task_command = SonarrCommand::StartTask {
task_name: SonarrTaskName::ApplicationUpdateCheck, task_name: SonarrTaskName::ApplicationUpdateCheck,
}; };
@@ -659,7 +659,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let test_indexer_command = SonarrCommand::TestIndexer { indexer_id: 1 }; let test_indexer_command = SonarrCommand::TestIndexer { indexer_id: 1 };
let result = SonarrCliHandler::with(&app_arc, test_indexer_command, &mut mock_network) let result = SonarrCliHandler::with(&app_arc, test_indexer_command, &mut mock_network)
@@ -681,7 +681,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let test_all_indexers_command = SonarrCommand::TestAllIndexers; let test_all_indexers_command = SonarrCommand::TestAllIndexers;
let result = SonarrCliHandler::with(&app_arc, test_all_indexers_command, &mut mock_network) let result = SonarrCliHandler::with(&app_arc, test_all_indexers_command, &mut mock_network)
@@ -706,7 +706,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let toggle_episode_monitoring_command = let toggle_episode_monitoring_command =
SonarrCommand::ToggleEpisodeMonitoring { episode_id: 1 }; SonarrCommand::ToggleEpisodeMonitoring { episode_id: 1 };
@@ -737,7 +737,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let toggle_season_monitoring_command = SonarrCommand::ToggleSeasonMonitoring { let toggle_season_monitoring_command = SonarrCommand::ToggleSeasonMonitoring {
series_id: 1, series_id: 1,
season_number: 1, season_number: 1,
@@ -174,7 +174,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let trigger_automatic_series_search_command = let trigger_automatic_series_search_command =
SonarrTriggerAutomaticSearchCommand::Series { series_id: 1 }; SonarrTriggerAutomaticSearchCommand::Series { series_id: 1 };
@@ -206,7 +206,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let trigger_automatic_season_search_command = SonarrTriggerAutomaticSearchCommand::Season { let trigger_automatic_season_search_command = SonarrTriggerAutomaticSearchCommand::Season {
series_id: 1, series_id: 1,
season_number: 1, season_number: 1,
@@ -238,7 +238,7 @@ mod tests {
json!({"testResponse": "response"}), json!({"testResponse": "response"}),
))) )))
}); });
let app_arc = Arc::new(Mutex::new(App::default())); let app_arc = Arc::new(Mutex::new(App::test_default()));
let trigger_automatic_episode_search_command = let trigger_automatic_episode_search_command =
SonarrTriggerAutomaticSearchCommand::Episode { episode_id: 1 }; SonarrTriggerAutomaticSearchCommand::Episode { episode_id: 1 };
+31 -31
View File
@@ -102,7 +102,7 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $block:expr, $context:expr) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $block:expr, $context:expr) => {
#[rstest] #[rstest]
fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app app
.data .data
@@ -110,14 +110,14 @@ mod test_utils {
.$data_ref .$data_ref
.set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]);
$handler::with(&key, &mut app, &$block, &$context).handle(); $handler::new(&key, &mut app, &$block, &$context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection(), app.data.$servarr_data.$data_ref.current_selection(),
"Test 2" "Test 2"
); );
$handler::with(&key, &mut app, &$block, &$context).handle(); $handler::new(&key, &mut app, &$block, &$context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection(), app.data.$servarr_data.$data_ref.current_selection(),
@@ -129,7 +129,7 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:ident, $block:expr, $context:expr, $field:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:ident, $block:expr, $context:expr, $field:ident) => {
#[rstest] #[rstest]
fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app app
.data .data
@@ -137,14 +137,14 @@ mod test_utils {
.$data_ref .$data_ref
.set_items(simple_stateful_iterable_vec!($items)); .set_items(simple_stateful_iterable_vec!($items));
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
"Test 2" "Test 2"
); );
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
@@ -156,18 +156,18 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident) => {
#[rstest] #[rstest]
fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app.data.$servarr_data.$data_ref.set_items($items); app.data.$servarr_data.$data_ref.set_items($items);
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
"Test 2" "Test 2"
); );
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
@@ -179,11 +179,11 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident, $conversion_fn:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident, $conversion_fn:ident) => {
#[rstest] #[rstest]
fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) { fn $func(#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app.data.$servarr_data.$data_ref.set_items($items); app.data.$servarr_data.$data_ref.set_items($items);
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app app
@@ -196,7 +196,7 @@ mod test_utils {
"Test 2" "Test 2"
); );
$handler::with(key, &mut app, $block, $context).handle(); $handler::new(key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app app
@@ -217,7 +217,7 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $block:expr, $context:expr) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $block:expr, $context:expr) => {
#[test] #[test]
fn $func() { fn $func() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app.data.$servarr_data.$data_ref.set_items(vec![ app.data.$servarr_data.$data_ref.set_items(vec![
"Test 1".to_owned(), "Test 1".to_owned(),
@@ -225,14 +225,14 @@ mod test_utils {
"Test 3".to_owned(), "Test 3".to_owned(),
]); ]);
$handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection(), app.data.$servarr_data.$data_ref.current_selection(),
"Test 3" "Test 3"
); );
$handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection(), app.data.$servarr_data.$data_ref.current_selection(),
@@ -244,7 +244,7 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:ident, $block:expr, $context:expr, $field:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:ident, $block:expr, $context:expr, $field:ident) => {
#[test] #[test]
fn $func() { fn $func() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app app
.data .data
@@ -252,14 +252,14 @@ mod test_utils {
.$data_ref .$data_ref
.set_items(extended_stateful_iterable_vec!($items)); .set_items(extended_stateful_iterable_vec!($items));
$handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
"Test 3" "Test 3"
); );
$handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
@@ -271,18 +271,18 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident) => {
#[test] #[test]
fn $func() { fn $func() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app.data.$servarr_data.$data_ref.set_items($items); app.data.$servarr_data.$data_ref.set_items($items);
$handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
"Test 3" "Test 3"
); );
$handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app.data.$servarr_data.$data_ref.current_selection().$field, app.data.$servarr_data.$data_ref.current_selection().$field,
@@ -294,11 +294,11 @@ mod test_utils {
($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident, $conversion_fn:ident) => { ($func:ident, $handler:ident, $servarr_data:ident, $data_ref:ident, $items:expr, $block:expr, $context:expr, $field:ident, $conversion_fn:ident) => {
#[test] #[test]
fn $func() { fn $func() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
app.data.$servarr_data.$data_ref.set_items($items); app.data.$servarr_data.$data_ref.set_items($items);
$handler::with(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.end.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app app
@@ -311,7 +311,7 @@ mod test_utils {
"Test 3" "Test 3"
); );
$handler::with(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle(); $handler::new(DEFAULT_KEYBINDINGS.home.key, &mut app, $block, $context).handle();
pretty_assertions::assert_str_eq!( pretty_assertions::assert_str_eq!(
app app
@@ -330,7 +330,7 @@ mod test_utils {
#[macro_export] #[macro_export]
macro_rules! test_handler_delegation { macro_rules! test_handler_delegation {
($handler:ident, $base:expr, $active_block:expr) => { ($handler:ident, $base:expr, $active_block:expr) => {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.history.set_items(vec![ app.data.sonarr_data.history.set_items(vec![
$crate::models::sonarr_models::SonarrHistoryItem::default(), $crate::models::sonarr_models::SonarrHistoryItem::default(),
]); ]);
@@ -417,7 +417,7 @@ mod test_utils {
app.push_navigation_stack($base.into()); app.push_navigation_stack($base.into());
app.push_navigation_stack($active_block.into()); app.push_navigation_stack($active_block.into());
$handler::with(DEFAULT_KEYBINDINGS.esc.key, &mut app, $active_block, None).handle(); $handler::new(DEFAULT_KEYBINDINGS.esc.key, &mut app, $active_block, None).handle();
pretty_assertions::assert_eq!(app.get_current_route(), $base.into()); pretty_assertions::assert_eq!(app.get_current_route(), $base.into());
}; };
@@ -426,15 +426,15 @@ mod test_utils {
#[macro_export] #[macro_export]
macro_rules! assert_delete_prompt { macro_rules! assert_delete_prompt {
($handler:ident, $block:expr, $expected_block:expr) => { ($handler:ident, $block:expr, $expected_block:expr) => {
let mut app = App::default(); let mut app = App::test_default();
$handler::with(DELETE_KEY, &mut app, $block, None).handle(); $handler::new(DELETE_KEY, &mut app, $block, None).handle();
pretty_assertions::assert_eq!(app.get_current_route(), $expected_block.into()); pretty_assertions::assert_eq!(app.get_current_route(), $expected_block.into());
}; };
($handler:ident, $app:expr, $block:expr, $expected_block:expr) => { ($handler:ident, $app:expr, $block:expr, $expected_block:expr) => {
$handler::with(DELETE_KEY, &mut $app, $block, None).handle(); $handler::new(DELETE_KEY, &mut $app, $block, None).handle();
pretty_assertions::assert_eq!($app.get_current_route(), $expected_block.into()); pretty_assertions::assert_eq!($app.get_current_route(), $expected_block.into());
}; };
@@ -443,10 +443,10 @@ mod test_utils {
#[macro_export] #[macro_export]
macro_rules! assert_refresh_key { macro_rules! assert_refresh_key {
($handler:ident, $block:expr) => { ($handler:ident, $block:expr) => {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack($block.into()); app.push_navigation_stack($block.into());
$handler::with(DEFAULT_KEYBINDINGS.refresh.key, &mut app, $block, None).handle(); $handler::new(DEFAULT_KEYBINDINGS.refresh.key, &mut app, $block, None).handle();
pretty_assertions::assert_eq!(app.get_current_route(), $block.into()); pretty_assertions::assert_eq!(app.get_current_route(), $block.into());
assert!(app.should_refresh); assert!(app.should_refresh);
+5 -5
View File
@@ -18,7 +18,7 @@ mod tests {
#[test] #[test]
fn test_handle_clear_errors() { fn test_handle_clear_errors() {
let mut app = App::default(); let mut app = App::test_default();
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
handle_clear_errors(&mut app); handle_clear_errors(&mut app);
@@ -30,7 +30,7 @@ mod tests {
#[case(ActiveRadarrBlock::Movies.into(), ActiveRadarrBlock::SearchMovie.into())] #[case(ActiveRadarrBlock::Movies.into(), ActiveRadarrBlock::SearchMovie.into())]
#[case(ActiveSonarrBlock::Series.into(), ActiveSonarrBlock::SearchSeries.into())] #[case(ActiveSonarrBlock::Series.into(), ActiveSonarrBlock::SearchSeries.into())]
fn test_handle_events(#[case] base_block: Route, #[case] top_block: Route) { fn test_handle_events(#[case] base_block: Route, #[case] top_block: Route) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(base_block); app.push_navigation_stack(base_block);
app.push_navigation_stack(top_block); app.push_navigation_stack(top_block);
app app
@@ -56,7 +56,7 @@ mod tests {
where where
T: Into<Route> + Copy, T: Into<Route> + Copy,
{ {
let mut app = App::default(); let mut app = App::test_default();
app.error = "Test".into(); app.error = "Test".into();
app.server_tabs.set_index(index); app.server_tabs.set_index(index);
@@ -84,7 +84,7 @@ mod tests {
#[rstest] #[rstest]
fn test_handle_prompt_toggle_left_right_radarr(#[values(Key::Left, Key::Right)] key: Key) { fn test_handle_prompt_toggle_left_right_radarr(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
@@ -100,7 +100,7 @@ mod tests {
#[rstest] #[rstest]
fn test_handle_prompt_toggle_left_right_sonarr(#[values(Key::Left, Key::Right)] key: Key) { fn test_handle_prompt_toggle_left_right_sonarr(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Series.into()); app.push_navigation_stack(ActiveSonarrBlock::Series.into());
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
+27 -26
View File
@@ -1,9 +1,9 @@
use radarr_handlers::RadarrHandler; use radarr_handlers::RadarrHandler;
use sonarr_handlers::SonarrHandler; use sonarr_handlers::SonarrHandler;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::matches_key;
use crate::models::{HorizontallyScrollableText, Route}; use crate::models::{HorizontallyScrollableText, Route};
mod radarr_handlers; mod radarr_handlers;
@@ -22,40 +22,42 @@ pub trait KeyEventHandler<'a, 'b, T: Into<Route> + Copy> {
fn handle_key_event(&mut self) { fn handle_key_event(&mut self) {
let key = self.get_key(); let key = self.get_key();
match key { match key {
_ if key == DEFAULT_KEYBINDINGS.up.key => { _ if matches_key!(up, key, self.ignore_alt_navigation()) => {
if self.is_ready() { if self.is_ready() {
self.handle_scroll_up(); self.handle_scroll_up();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.down.key => { _ if matches_key!(down, key, self.ignore_alt_navigation()) => {
if self.is_ready() { if self.is_ready() {
self.handle_scroll_down(); self.handle_scroll_down();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.home.key => { _ if matches_key!(home, key) => {
if self.is_ready() { if self.is_ready() {
self.handle_home(); self.handle_home();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.end.key => { _ if matches_key!(end, key) => {
if self.is_ready() { if self.is_ready() {
self.handle_end(); self.handle_end();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.delete.key => { _ if matches_key!(delete, key) => {
if self.is_ready() { if self.is_ready() {
self.handle_delete(); self.handle_delete();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.left.key || key == DEFAULT_KEYBINDINGS.right.key => { _ if matches_key!(left, key, self.ignore_alt_navigation())
|| matches_key!(right, key, self.ignore_alt_navigation()) =>
{
self.handle_left_right_action() self.handle_left_right_action()
} }
_ if key == DEFAULT_KEYBINDINGS.submit.key => { _ if matches_key!(submit, key) => {
if self.is_ready() { if self.is_ready() {
self.handle_submit(); self.handle_submit();
} }
} }
_ if key == DEFAULT_KEYBINDINGS.esc.key => self.handle_esc(), _ if matches_key!(esc, key) => self.handle_esc(),
_ => { _ => {
if self.is_ready() { if self.is_ready() {
self.handle_char_key_event(); self.handle_char_key_event();
@@ -69,8 +71,9 @@ pub trait KeyEventHandler<'a, 'b, T: Into<Route> + Copy> {
} }
fn accepts(active_block: T) -> bool; fn accepts(active_block: T) -> bool;
fn with(key: Key, app: &'a mut App<'b>, active_block: T, context: Option<T>) -> Self; fn new(key: Key, app: &'a mut App<'b>, active_block: T, context: Option<T>) -> Self;
fn get_key(&self) -> Key; fn get_key(&self) -> Key;
fn ignore_alt_navigation(&self) -> bool;
fn is_ready(&self) -> bool; fn is_ready(&self) -> bool;
fn handle_scroll_up(&mut self); fn handle_scroll_up(&mut self);
fn handle_scroll_down(&mut self); fn handle_scroll_down(&mut self);
@@ -84,12 +87,12 @@ pub trait KeyEventHandler<'a, 'b, T: Into<Route> + Copy> {
} }
pub fn handle_events(key: Key, app: &mut App<'_>) { pub fn handle_events(key: Key, app: &mut App<'_>) {
if key == DEFAULT_KEYBINDINGS.next_servarr.key { if matches_key!(next_servarr, key) {
app.reset(); app.reset();
app.server_tabs.next(); app.server_tabs.next();
app.pop_and_push_navigation_stack(app.server_tabs.get_active_route()); app.pop_and_push_navigation_stack(app.server_tabs.get_active_route());
app.cancellation_token.cancel(); app.cancellation_token.cancel();
} else if key == DEFAULT_KEYBINDINGS.previous_servarr.key { } else if matches_key!(previous_servarr, key) {
app.reset(); app.reset();
app.server_tabs.previous(); app.server_tabs.previous();
app.pop_and_push_navigation_stack(app.server_tabs.get_active_route()); app.pop_and_push_navigation_stack(app.server_tabs.get_active_route());
@@ -97,10 +100,10 @@ pub fn handle_events(key: Key, app: &mut App<'_>) {
} else { } else {
match app.get_current_route() { match app.get_current_route() {
Route::Radarr(active_radarr_block, context) => { Route::Radarr(active_radarr_block, context) => {
RadarrHandler::with(key, app, active_radarr_block, context).handle() RadarrHandler::new(key, app, active_radarr_block, context).handle()
} }
Route::Sonarr(active_sonarr_block, context) => { Route::Sonarr(active_sonarr_block, context) => {
SonarrHandler::with(key, app, active_sonarr_block, context).handle() SonarrHandler::new(key, app, active_sonarr_block, context).handle()
} }
_ => (), _ => (),
} }
@@ -115,17 +118,15 @@ fn handle_clear_errors(app: &mut App<'_>) {
fn handle_prompt_toggle(app: &mut App<'_>, key: Key) { fn handle_prompt_toggle(app: &mut App<'_>, key: Key) {
match key { match key {
_ if key == DEFAULT_KEYBINDINGS.left.key || key == DEFAULT_KEYBINDINGS.right.key => { _ if matches_key!(left, key) || matches_key!(right, key) => match app.get_current_route() {
match app.get_current_route() { Route::Radarr(_, _) => {
Route::Radarr(_, _) => { app.data.radarr_data.prompt_confirm = !app.data.radarr_data.prompt_confirm
app.data.radarr_data.prompt_confirm = !app.data.radarr_data.prompt_confirm
}
Route::Sonarr(_, _) => {
app.data.sonarr_data.prompt_confirm = !app.data.sonarr_data.prompt_confirm
}
_ => (),
} }
} Route::Sonarr(_, _) => {
app.data.sonarr_data.prompt_confirm = !app.data.sonarr_data.prompt_confirm
}
_ => (),
},
_ => (), _ => (),
} }
} }
@@ -149,7 +150,7 @@ macro_rules! handle_text_box_left_right_keys {
macro_rules! handle_text_box_keys { macro_rules! handle_text_box_keys {
($self:expr, $key:expr, $input:expr) => { ($self:expr, $key:expr, $input:expr) => {
match $self.key { match $self.key {
_ if $key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.backspace.key => { _ if $crate::matches_key!(backspace, $key) => {
$input.pop(); $input.pop();
} }
Key::Char(character) => { Key::Char(character) => {
@@ -165,7 +166,7 @@ macro_rules! handle_prompt_left_right_keys {
($self:expr, $confirm_prompt:expr, $data:ident) => { ($self:expr, $confirm_prompt:expr, $data:ident) => {
if $self.app.data.$data.selected_block.get_active_block() == $confirm_prompt { if $self.app.data.$data.selected_block.get_active_block() == $confirm_prompt {
handle_prompt_toggle($self.app, $self.key); handle_prompt_toggle($self.app, $self.key);
} else if $self.key == $crate::app::key_binding::DEFAULT_KEYBINDINGS.left.key { } else if $crate::matches_key!(left, $self.key) {
$self.app.data.$data.selected_block.left(); $self.app.data.$data.selected_block.left();
} else { } else {
$self.app.data.$data.selected_block.right(); $self.app.data.$data.selected_block.right();
@@ -4,6 +4,7 @@ mod tests {
use chrono::DateTime; use chrono::DateTime;
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -24,10 +25,10 @@ mod tests {
#[test] #[test]
fn test_delete_blocklist_item_prompt() { fn test_delete_blocklist_item_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); BlocklistHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -37,12 +38,12 @@ mod tests {
#[test] #[test]
fn test_delete_blocklist_item_no_op_when_not_ready() { fn test_delete_blocklist_item_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); BlocklistHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into());
} }
@@ -56,11 +57,11 @@ mod tests {
#[rstest] #[rstest]
fn test_blocklist_tab_left(#[values(true, false)] is_ready: bool) { fn test_blocklist_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(3); app.data.radarr_data.main_tabs.set_index(3);
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -77,11 +78,11 @@ mod tests {
#[rstest] #[rstest]
fn test_blocklist_tab_right(#[values(true, false)] is_ready: bool) { fn test_blocklist_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(3); app.data.radarr_data.main_tabs.set_index(3);
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -108,13 +109,13 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
BlocklistHandler::with(key, &mut app, active_radarr_block, None).handle(); BlocklistHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
BlocklistHandler::with(key, &mut app, active_radarr_block, None).handle(); BlocklistHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -132,11 +133,11 @@ mod tests {
#[test] #[test]
fn test_blocklist_submit() { fn test_blocklist_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -146,12 +147,12 @@ mod tests {
#[test] #[test]
fn test_blocklist_submit_no_op_when_not_ready() { fn test_blocklist_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into());
} }
@@ -172,13 +173,13 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -196,12 +197,12 @@ mod tests {
)] )]
prompt_block: ActiveRadarrBlock, prompt_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None); assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
@@ -232,12 +233,12 @@ mod tests {
#[case] base_block: ActiveRadarrBlock, #[case] base_block: ActiveRadarrBlock,
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(base_block.into()); app.push_navigation_stack(base_block.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
BlocklistHandler::with(ESC_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(ESC_KEY, &mut app, prompt_block, None).handle();
assert_eq!(app.get_current_route(), base_block.into()); assert_eq!(app.get_current_route(), base_block.into());
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
@@ -245,11 +246,11 @@ mod tests {
#[test] #[test]
fn test_esc_blocklist_item_details() { fn test_esc_blocklist_item_details() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.push_navigation_stack(ActiveRadarrBlock::BlocklistItemDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::BlocklistItemDetails.into());
BlocklistHandler::with( BlocklistHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::BlocklistItemDetails, ActiveRadarrBlock::BlocklistItemDetails,
@@ -262,13 +263,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
DownloadsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle(); DownloadsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Blocklist.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -285,11 +286,11 @@ mod tests {
#[test] #[test]
fn test_refresh_blocklist_key() { fn test_refresh_blocklist_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -303,12 +304,12 @@ mod tests {
#[test] #[test]
fn test_refresh_blocklist_key_no_op_when_not_ready() { fn test_refresh_blocklist_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -322,10 +323,10 @@ mod tests {
#[test] #[test]
fn test_clear_blocklist_key() { fn test_clear_blocklist_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.clear.key, DEFAULT_KEYBINDINGS.clear.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -341,12 +342,12 @@ mod tests {
#[test] #[test]
fn test_clear_blocklist_key_no_op_when_not_ready() { fn test_clear_blocklist_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveRadarrBlock::Blocklist.into());
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.clear.key, DEFAULT_KEYBINDINGS.clear.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -373,12 +374,12 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
prompt_block, prompt_block,
@@ -541,12 +542,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_blocklist_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_blocklist_item_id() { fn test_extract_blocklist_item_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.blocklist.set_items(blocklist_vec()); app.data.radarr_data.blocklist.set_items(blocklist_vec());
let blocklist_item_id = BlocklistHandler::with( let blocklist_item_id = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -559,10 +576,10 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_not_ready_when_loading() { fn test_blocklist_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -574,10 +591,10 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_not_ready_when_blocklist_is_empty() { fn test_blocklist_handler_not_ready_when_blocklist_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
@@ -589,7 +606,7 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_ready_when_not_loading_and_blocklist_is_not_empty() { fn test_blocklist_handler_ready_when_not_loading_and_blocklist_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -597,7 +614,7 @@ mod tests {
.blocklist .blocklist
.set_items(vec![BlocklistItem::default()]); .set_items(vec![BlocklistItem::default()]);
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Blocklist,
+11 -8
View File
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
@@ -9,6 +7,7 @@ use crate::models::radarr_models::BlocklistItem;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, BLOCKLIST_BLOCKS};
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "blocklist_handler_tests.rs"] #[path = "blocklist_handler_tests.rs"]
@@ -21,7 +20,7 @@ pub(super) struct BlocklistHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> BlocklistHandler<'a, 'b> { impl BlocklistHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
blocklist, blocklist,
@@ -51,7 +50,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
BLOCKLIST_BLOCKS.contains(&active_block) BLOCKLIST_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -143,10 +146,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Blocklist => match self.key { ActiveRadarrBlock::Blocklist => match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ if key == DEFAULT_KEYBINDINGS.clear.key => { _ if matches_key!(clear, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::BlocklistClearAllItemsPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::BlocklistClearAllItemsPrompt.into());
@@ -154,7 +157,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
_ => (), _ => (),
}, },
ActiveRadarrBlock::DeleteBlocklistItemPrompt => { ActiveRadarrBlock::DeleteBlocklistItemPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteBlocklistItem( self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DeleteBlocklistItem(
self.extract_blocklist_item_id(), self.extract_blocklist_item_id(),
@@ -164,7 +167,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for BlocklistHandler<'a,
} }
} }
ActiveRadarrBlock::BlocklistClearAllItemsPrompt => { ActiveRadarrBlock::BlocklistClearAllItemsPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::ClearBlocklist); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::ClearBlocklist);
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::KeyEventHandler; use crate::handlers::KeyEventHandler;
use crate::models::radarr_models::CollectionMovie; use crate::models::radarr_models::CollectionMovie;
@@ -11,6 +9,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
}; };
use crate::models::stateful_table::StatefulTable; use crate::models::stateful_table::StatefulTable;
use crate::models::BlockSelectionState; use crate::models::BlockSelectionState;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "collection_details_handler_tests.rs"] #[path = "collection_details_handler_tests.rs"]
@@ -23,7 +22,7 @@ pub(super) struct CollectionDetailsHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> CollectionDetailsHandler<'a, 'b> { impl CollectionDetailsHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
collection_movies, collection_movies,
@@ -46,7 +45,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan
COLLECTION_DETAILS_BLOCKS.contains(&active_block) COLLECTION_DETAILS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -130,7 +133,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionDetailsHan
fn handle_char_key_event(&mut self) { fn handle_char_key_event(&mut self) {
if self.active_radarr_block == ActiveRadarrBlock::CollectionDetails if self.active_radarr_block == ActiveRadarrBlock::CollectionDetails
&& self.key == DEFAULT_KEYBINDINGS.edit.key && matches_key!(edit, self.key)
{ {
self.app.push_navigation_stack( self.app.push_navigation_stack(
( (
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_str_eq; use pretty_assertions::assert_str_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -27,7 +28,7 @@ mod tests {
#[test] #[test]
fn test_collection_details_submit() { fn test_collection_details_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -42,7 +43,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, ADD_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, ADD_MOVIE_SELECTION_BLOCKS.len() - 1);
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -104,7 +105,7 @@ mod tests {
#[test] #[test]
fn test_collection_details_submit_no_op_when_not_ready() { fn test_collection_details_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app app
@@ -113,7 +114,7 @@ mod tests {
.collection_movies .collection_movies
.set_items(vec![CollectionMovie::default()]); .set_items(vec![CollectionMovie::default()]);
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -130,7 +131,7 @@ mod tests {
#[test] #[test]
fn test_collection_details_submit_movie_already_in_library() { fn test_collection_details_submit_movie_already_in_library() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -142,7 +143,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -166,7 +167,7 @@ mod tests {
#[rstest] #[rstest]
fn test_esc_collection_details(#[values(true, false)] is_ready: bool) { fn test_esc_collection_details(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
@@ -176,7 +177,7 @@ mod tests {
.collection_movies .collection_movies
.set_items(vec![CollectionMovie::default()]); .set_items(vec![CollectionMovie::default()]);
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -193,11 +194,11 @@ mod tests {
#[test] #[test]
fn test_esc_view_movie_overview() { fn test_esc_view_movie_overview() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into()); app.push_navigation_stack(ActiveRadarrBlock::ViewMovieOverview.into());
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::ViewMovieOverview, ActiveRadarrBlock::ViewMovieOverview,
@@ -237,7 +238,7 @@ mod tests {
#[test] #[test]
fn test_edit_key_no_op_when_not_ready() { fn test_edit_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::CollectionDetails.into());
let mut radarr_data = create_test_radarr_data(); let mut radarr_data = create_test_radarr_data();
@@ -251,7 +252,7 @@ mod tests {
}]); }]);
app.data.radarr_data = radarr_data; app.data.radarr_data = radarr_data;
CollectionDetailsHandler::with( CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.edit.key, DEFAULT_KEYBINDINGS.edit.key,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -278,12 +279,28 @@ mod tests {
}); });
} }
#[rstest]
fn test_collection_details_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_collection_details_handler_not_ready_when_loading() { fn test_collection_details_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = CollectionDetailsHandler::with( let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -295,10 +312,10 @@ mod tests {
#[test] #[test]
fn test_collection_details_handler_not_ready_when_collection_movies_is_empty() { fn test_collection_details_handler_not_ready_when_collection_movies_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = CollectionDetailsHandler::with( let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -310,7 +327,7 @@ mod tests {
#[test] #[test]
fn test_collection_details_handler_ready_when_not_loading_and_collection_movies_is_not_empty() { fn test_collection_details_handler_ready_when_not_loading_and_collection_movies_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -318,7 +335,7 @@ mod tests {
.collection_movies .collection_movies
.set_items(vec![CollectionMovie::default()]); .set_items(vec![CollectionMovie::default()]);
let handler = CollectionDetailsHandler::with( let handler = CollectionDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::CollectionDetails, ActiveRadarrBlock::CollectionDetails,
@@ -28,11 +28,11 @@ mod tests {
#[rstest] #[rstest]
fn test_collections_tab_left(#[values(true, false)] is_ready: bool) { fn test_collections_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(1); app.data.radarr_data.main_tabs.set_index(1);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -49,11 +49,11 @@ mod tests {
#[rstest] #[rstest]
fn test_collections_tab_right(#[values(true, false)] is_ready: bool) { fn test_collections_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(1); app.data.radarr_data.main_tabs.set_index(1);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -72,9 +72,9 @@ mod tests {
fn test_left_right_update_all_collections_prompt_toggle( fn test_left_right_update_all_collections_prompt_toggle(
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
CollectionsHandler::with( CollectionsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -84,7 +84,7 @@ mod tests {
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
CollectionsHandler::with( CollectionsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -107,14 +107,14 @@ mod tests {
#[test] #[test]
fn test_collections_submit() { fn test_collections_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle(); CollectionsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -124,7 +124,7 @@ mod tests {
#[test] #[test]
fn test_collections_submit_no_op_when_not_ready() { fn test_collections_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app app
@@ -133,7 +133,7 @@ mod tests {
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle(); CollectionsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -143,7 +143,7 @@ mod tests {
#[test] #[test]
fn test_update_all_collections_prompt_confirm_submit() { fn test_update_all_collections_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -153,7 +153,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
CollectionsHandler::with( CollectionsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -174,7 +174,7 @@ mod tests {
#[test] #[test]
fn test_update_all_collections_prompt_decline_submit() { fn test_update_all_collections_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -183,7 +183,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
CollectionsHandler::with( CollectionsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -211,12 +211,12 @@ mod tests {
#[test] #[test]
fn test_update_all_collections_prompt_block_esc() { fn test_update_all_collections_prompt_block_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
CollectionsHandler::with( CollectionsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -233,14 +233,14 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
CollectionsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle(); CollectionsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::Collections, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -272,7 +272,7 @@ mod tests {
#[test] #[test]
fn test_collection_edit_key_no_op_when_not_ready() { fn test_collection_edit_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
let mut radarr_data = create_test_radarr_data(); let mut radarr_data = create_test_radarr_data();
@@ -286,7 +286,7 @@ mod tests {
}]); }]);
app.data.radarr_data = radarr_data; app.data.radarr_data = radarr_data;
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.edit.key, DEFAULT_KEYBINDINGS.edit.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -303,14 +303,14 @@ mod tests {
#[test] #[test]
fn test_update_key() { fn test_update_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -326,7 +326,7 @@ mod tests {
#[test] #[test]
fn test_update_key_no_op_when_not_ready() { fn test_update_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app app
@@ -335,7 +335,7 @@ mod tests {
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -351,7 +351,7 @@ mod tests {
#[test] #[test]
fn test_refresh_collections_key() { fn test_refresh_collections_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app app
.data .data
@@ -359,7 +359,7 @@ mod tests {
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -376,7 +376,7 @@ mod tests {
#[test] #[test]
fn test_refresh_collections_key_no_op_when_not_ready() { fn test_refresh_collections_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app app
@@ -385,7 +385,7 @@ mod tests {
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -402,7 +402,7 @@ mod tests {
#[test] #[test]
fn test_update_all_collections_prompt_confirm_confirm() { fn test_update_all_collections_prompt_confirm_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -411,7 +411,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
CollectionsHandler::with( CollectionsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllCollectionsPrompt, ActiveRadarrBlock::UpdateAllCollectionsPrompt,
@@ -589,12 +589,28 @@ mod tests {
}); });
} }
#[rstest]
fn test_collections_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = CollectionsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_collections_handler_not_ready_when_loading() { fn test_collections_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = CollectionsHandler::with( let handler = CollectionsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -606,10 +622,10 @@ mod tests {
#[test] #[test]
fn test_collections_handler_not_ready_when_collections_is_empty() { fn test_collections_handler_not_ready_when_collections_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = CollectionsHandler::with( let handler = CollectionsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -621,7 +637,7 @@ mod tests {
#[test] #[test]
fn test_collections_handler_ready_when_not_loading_and_collections_is_not_empty() { fn test_collections_handler_ready_when_not_loading_and_collections_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -629,7 +645,7 @@ mod tests {
.collections .collections
.set_items(vec![Collection::default()]); .set_items(vec![Collection::default()]);
let handler = CollectionsHandler::with( let handler = CollectionsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Collections, ActiveRadarrBlock::Collections,
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -7,7 +6,7 @@ use crate::models::servarr_data::radarr::modals::EditCollectionModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_COLLECTION_BLOCKS};
use crate::models::Scrollable; use crate::models::Scrollable;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{handle_text_box_keys, handle_text_box_left_right_keys, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "edit_collection_handler_tests.rs"] #[path = "edit_collection_handler_tests.rs"]
@@ -20,8 +19,15 @@ pub(super) struct EditCollectionHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> EditCollectionHandler<'a, 'b> { impl EditCollectionHandler<'_, '_> {
fn build_edit_collection_params(&mut self) -> EditCollectionParams { fn build_edit_collection_params(&mut self) -> EditCollectionParams {
let edit_collection_modal = self
.app
.data
.radarr_data
.edit_collection_modal
.take()
.expect("EditCollectionModal is None");
let collection_id = self.app.data.radarr_data.collections.current_selection().id; let collection_id = self.app.data.radarr_data.collections.current_selection().id;
let EditCollectionModal { let EditCollectionModal {
path, path,
@@ -29,13 +35,7 @@ impl<'a, 'b> EditCollectionHandler<'a, 'b> {
minimum_availability_list, minimum_availability_list,
monitored, monitored,
quality_profile_list, quality_profile_list,
} = self } = edit_collection_modal;
.app
.data
.radarr_data
.edit_collection_modal
.as_ref()
.unwrap();
let quality_profile = quality_profile_list.current_selection(); let quality_profile = quality_profile_list.current_selection();
let quality_profile_id = *self let quality_profile_id = *self
.app .app
@@ -48,15 +48,13 @@ impl<'a, 'b> EditCollectionHandler<'a, 'b> {
.next() .next()
.unwrap(); .unwrap();
let root_folder_path: String = path.text.clone(); let root_folder_path = path.text;
let monitored = monitored.unwrap_or_default();
let search_on_add = search_on_add.unwrap_or_default(); let search_on_add = search_on_add.unwrap_or_default();
let minimum_availability = *minimum_availability_list.current_selection(); let minimum_availability = *minimum_availability_list.current_selection();
self.app.data.radarr_data.edit_collection_modal = None;
EditCollectionParams { EditCollectionParams {
collection_id, collection_id,
monitored: Some(monitored), monitored,
minimum_availability: Some(minimum_availability), minimum_availability: Some(minimum_availability),
quality_profile_id: Some(quality_profile_id), quality_profile_id: Some(quality_profile_id),
root_folder_path: Some(root_folder_path), root_folder_path: Some(root_folder_path),
@@ -70,7 +68,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle
EDIT_COLLECTION_BLOCKS.contains(&active_block) EDIT_COLLECTION_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -355,7 +357,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditCollectionHandle
ActiveRadarrBlock::EditCollectionPrompt => { ActiveRadarrBlock::EditCollectionPrompt => {
if self.app.data.radarr_data.selected_block.get_active_block() if self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::EditCollectionConfirmPrompt == ActiveRadarrBlock::EditCollectionConfirmPrompt
&& key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection( self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::EditCollection(
@@ -2,6 +2,7 @@
mod tests { mod tests {
use bimap::BiMap; use bimap::BiMap;
use pretty_assertions::assert_str_eq; use pretty_assertions::assert_str_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -32,7 +33,7 @@ mod tests {
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app app
.data .data
@@ -45,7 +46,7 @@ mod tests {
if key == Key::Up { if key == Key::Up {
for i in (0..minimum_availability_vec.len()).rev() { for i in (0..minimum_availability_vec.len()).rev() {
EditCollectionHandler::with( EditCollectionHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
@@ -67,7 +68,7 @@ mod tests {
} }
} else { } else {
for i in 0..minimum_availability_vec.len() { for i in 0..minimum_availability_vec.len() {
EditCollectionHandler::with( EditCollectionHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
@@ -94,7 +95,7 @@ mod tests {
fn test_edit_collection_select_quality_profile_scroll( fn test_edit_collection_select_quality_profile_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app app
.data .data
@@ -105,7 +106,7 @@ mod tests {
.quality_profile_list .quality_profile_list
.set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]);
EditCollectionHandler::with( EditCollectionHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectQualityProfile, ActiveRadarrBlock::EditCollectionSelectQualityProfile,
@@ -125,7 +126,7 @@ mod tests {
"Test 2" "Test 2"
); );
EditCollectionHandler::with( EditCollectionHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectQualityProfile, ActiveRadarrBlock::EditCollectionSelectQualityProfile,
@@ -148,13 +149,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_collection_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_collection_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditCollectionHandler::with(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None) EditCollectionHandler::new(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None)
.handle(); .handle();
if key == Key::Up { if key == Key::Up {
@@ -174,14 +175,14 @@ mod tests {
fn test_edit_collection_prompt_scroll_no_op_when_not_ready( fn test_edit_collection_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditCollectionHandler::with(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None) EditCollectionHandler::new(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None)
.handle(); .handle();
assert_eq!( assert_eq!(
@@ -204,7 +205,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_select_minimum_availability_home_end() { fn test_edit_collection_select_minimum_availability_home_end() {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app app
.data .data
@@ -215,7 +216,7 @@ mod tests {
.minimum_availability_list .minimum_availability_list
.set_items(minimum_availability_vec.clone()); .set_items(minimum_availability_vec.clone());
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
@@ -235,7 +236,7 @@ mod tests {
&minimum_availability_vec[minimum_availability_vec.len() - 1] &minimum_availability_vec[minimum_availability_vec.len() - 1]
); );
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectMinimumAvailability, ActiveRadarrBlock::EditCollectionSelectMinimumAvailability,
@@ -258,7 +259,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_select_quality_profile_scroll() { fn test_edit_collection_select_quality_profile_scroll() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app app
.data .data
@@ -273,7 +274,7 @@ mod tests {
"Test 3".to_owned(), "Test 3".to_owned(),
]); ]);
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectQualityProfile, ActiveRadarrBlock::EditCollectionSelectQualityProfile,
@@ -293,7 +294,7 @@ mod tests {
"Test 3" "Test 3"
); );
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionSelectQualityProfile, ActiveRadarrBlock::EditCollectionSelectQualityProfile,
@@ -316,13 +317,13 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_home_end_keys() { fn test_edit_collection_root_folder_path_input_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal {
path: "Test".into(), path: "Test".into(),
..EditCollectionModal::default() ..EditCollectionModal::default()
}); });
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -343,7 +344,7 @@ mod tests {
4 4
); );
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -376,14 +377,14 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
EditCollectionHandler::with(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None) EditCollectionHandler::new(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None)
.handle(); .handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
EditCollectionHandler::with(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None) EditCollectionHandler::new(key, &mut app, ActiveRadarrBlock::EditCollectionPrompt, None)
.handle(); .handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
@@ -391,13 +392,13 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_left_right_keys() { fn test_edit_collection_root_folder_path_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal {
path: "Test".into(), path: "Test".into(),
..EditCollectionModal::default() ..EditCollectionModal::default()
}); });
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -418,7 +419,7 @@ mod tests {
1 1
); );
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -456,7 +457,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_submit() { fn test_edit_collection_root_folder_path_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal {
path: "Test Path".into(), path: "Test Path".into(),
@@ -465,7 +466,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into());
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -491,7 +492,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_prompt_prompt_decline_submit() { fn test_edit_collection_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
@@ -503,7 +504,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -520,7 +521,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_confirm_prompt_prompt_confirmation_submit() { fn test_edit_collection_confirm_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_collection_modal = EditCollectionModal { let mut edit_collection_modal = EditCollectionModal {
path: "/nfs/Test Path".into(), path: "/nfs/Test Path".into(),
monitored: Some(false), monitored: Some(false),
@@ -560,7 +561,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -582,7 +583,7 @@ mod tests {
#[test] #[test]
fn test_edit_collection_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_collection_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
@@ -596,7 +597,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -618,13 +619,13 @@ mod tests {
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
Some(ActiveRadarrBlock::Collections), Some(ActiveRadarrBlock::Collections),
)); ));
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
app.push_navigation_stack(current_route); app.push_navigation_stack(current_route);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -644,7 +645,7 @@ mod tests {
Some(true) Some(true)
); );
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -671,7 +672,7 @@ mod tests {
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
Some(ActiveRadarrBlock::Collections), Some(ActiveRadarrBlock::Collections),
)); ));
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
@@ -682,7 +683,7 @@ mod tests {
.set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 2); .set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 2);
app.push_navigation_stack(current_route); app.push_navigation_stack(current_route);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -702,7 +703,7 @@ mod tests {
Some(true) Some(true)
); );
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -731,7 +732,7 @@ mod tests {
#[case] selected_block: ActiveRadarrBlock, #[case] selected_block: ActiveRadarrBlock,
#[case] index: usize, #[case] index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack( app.push_navigation_stack(
( (
@@ -744,7 +745,7 @@ mod tests {
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, index); app.data.radarr_data.selected_block.set_index(0, index);
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -772,12 +773,12 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
EditCollectionHandler::with( EditCollectionHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -808,14 +809,14 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_esc() { fn test_edit_collection_root_folder_path_input_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionRootFolderPathInput.into());
EditCollectionHandler::with( EditCollectionHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -832,12 +833,12 @@ mod tests {
#[test] #[test]
fn test_edit_collection_prompt_esc() { fn test_edit_collection_prompt_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
EditCollectionHandler::with( EditCollectionHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -864,13 +865,13 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool, #[values(true, false)] is_ready: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(ActiveRadarrBlock::Collections.into()); app.push_navigation_stack(ActiveRadarrBlock::Collections.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
EditCollectionHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); EditCollectionHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -893,13 +894,13 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_backspace() { fn test_edit_collection_root_folder_path_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal { app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal {
path: "Test".into(), path: "Test".into(),
..EditCollectionModal::default() ..EditCollectionModal::default()
}); });
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
@@ -922,11 +923,11 @@ mod tests {
#[test] #[test]
fn test_edit_collection_root_folder_path_input_char_key() { fn test_edit_collection_root_folder_path_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
EditCollectionHandler::with( EditCollectionHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionRootFolderPathInput, ActiveRadarrBlock::EditCollectionRootFolderPathInput,
None, None,
@@ -942,13 +943,13 @@ mod tests {
.unwrap() .unwrap()
.path .path
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_collection_confirm_prompt_prompt_confirmation_confirm() { fn test_edit_collection_confirm_prompt_prompt_confirmation_confirm() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_collection_modal = EditCollectionModal { let mut edit_collection_modal = EditCollectionModal {
path: "/nfs/Test Path".into(), path: "/nfs/Test Path".into(),
monitored: Some(false), monitored: Some(false),
@@ -987,7 +988,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_COLLECTION_SELECTION_BLOCKS.len() - 1);
EditCollectionHandler::with( EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -1019,9 +1020,25 @@ mod tests {
}); });
} }
#[rstest]
fn test_edit_collection_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_collection_params() { fn test_build_edit_collection_params() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_collection_modal = EditCollectionModal { let mut edit_collection_modal = EditCollectionModal {
path: "/nfs/Test Path".into(), path: "/nfs/Test Path".into(),
monitored: Some(false), monitored: Some(false),
@@ -1051,7 +1068,7 @@ mod tests {
search_on_add: Some(false), search_on_add: Some(false),
}; };
let edit_collection_params = EditCollectionHandler::with( let edit_collection_params = EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -1065,10 +1082,10 @@ mod tests {
#[test] #[test]
fn test_edit_collection_handler_is_not_ready_when_loading() { fn test_edit_collection_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = EditCollectionHandler::with( let handler = EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -1080,10 +1097,10 @@ mod tests {
#[test] #[test]
fn test_edit_collection_handler_is_not_ready_when_edit_collection_modal_is_none() { fn test_edit_collection_handler_is_not_ready_when_edit_collection_modal_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = EditCollectionHandler::with( let handler = EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
@@ -1095,11 +1112,11 @@ mod tests {
#[test] #[test]
fn test_edit_collection_handler_is_ready_when_edit_collection_modal_is_some() { fn test_edit_collection_handler_is_ready_when_edit_collection_modal_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default()); app.data.radarr_data.edit_collection_modal = Some(EditCollectionModal::default());
let handler = EditCollectionHandler::with( let handler = EditCollectionHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditCollectionPrompt, ActiveRadarrBlock::EditCollectionPrompt,
+14 -16
View File
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler; use crate::handlers::radarr_handlers::collections::collection_details_handler::CollectionDetailsHandler;
use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler; use crate::handlers::radarr_handlers::collections::edit_collection_handler::EditCollectionHandler;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
@@ -14,6 +12,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::models::BlockSelectionState; use crate::models::BlockSelectionState;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
mod collection_details_handler; mod collection_details_handler;
mod edit_collection_handler; mod edit_collection_handler;
@@ -29,7 +28,7 @@ pub(super) struct CollectionsHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> CollectionsHandler<'a, 'b> { impl CollectionsHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
collections, collections,
@@ -55,16 +54,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
if !self.handle_collections_table_events(collections_table_handling_config) { if !self.handle_collections_table_events(collections_table_handling_config) {
match self.active_radarr_block { match self.active_radarr_block {
_ if CollectionDetailsHandler::accepts(self.active_radarr_block) => { _ if CollectionDetailsHandler::accepts(self.active_radarr_block) => {
CollectionDetailsHandler::with( CollectionDetailsHandler::new(self.key, self.app, self.active_radarr_block, self.context)
self.key, .handle();
self.app,
self.active_radarr_block,
self.context,
)
.handle();
} }
_ if EditCollectionHandler::accepts(self.active_radarr_block) => { _ if EditCollectionHandler::accepts(self.active_radarr_block) => {
EditCollectionHandler::with(self.key, self.app, self.active_radarr_block, self.context) EditCollectionHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle(); .handle();
} }
_ => self.handle_key_event(), _ => self.handle_key_event(),
@@ -78,7 +72,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
|| COLLECTIONS_BLOCKS.contains(&active_block) || COLLECTIONS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -150,7 +148,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Collections => match self.key { ActiveRadarrBlock::Collections => match self.key {
_ if key == DEFAULT_KEYBINDINGS.edit.key => { _ if matches_key!(edit, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::EditCollectionPrompt.into());
@@ -159,18 +157,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for CollectionsHandler<'
self.app.data.radarr_data.selected_block = self.app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_COLLECTION_SELECTION_BLOCKS);
} }
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::UpdateAllCollectionsPrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::UpdateAllCollectionsPrompt => { ActiveRadarrBlock::UpdateAllCollectionsPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateCollections); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateCollections);
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -21,14 +22,14 @@ mod tests {
#[test] #[test]
fn test_delete_download_prompt() { fn test_delete_download_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle(); DownloadsHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -38,7 +39,7 @@ mod tests {
#[test] #[test]
fn test_delete_download_prompt_no_op_when_not_ready() { fn test_delete_download_prompt_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app app
@@ -47,7 +48,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle(); DownloadsHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Downloads.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Downloads.into());
} }
@@ -61,11 +62,11 @@ mod tests {
#[rstest] #[rstest]
fn test_downloads_tab_left(#[values(true, false)] is_ready: bool) { fn test_downloads_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(2); app.data.radarr_data.main_tabs.set_index(2);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -85,11 +86,11 @@ mod tests {
#[rstest] #[rstest]
fn test_downloads_tab_right(#[values(true, false)] is_ready: bool) { fn test_downloads_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(2); app.data.radarr_data.main_tabs.set_index(2);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -113,13 +114,13 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
DownloadsHandler::with(key, &mut app, active_radarr_block, None).handle(); DownloadsHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
DownloadsHandler::with(key, &mut app, active_radarr_block, None).handle(); DownloadsHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -151,7 +152,7 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -161,7 +162,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -178,7 +179,7 @@ mod tests {
#[case] base_route: ActiveRadarrBlock, #[case] base_route: ActiveRadarrBlock,
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -187,7 +188,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.data.radarr_data.prompt_confirm_action, None); assert_eq!(app.data.radarr_data.prompt_confirm_action, None);
@@ -210,12 +211,12 @@ mod tests {
#[case] base_block: ActiveRadarrBlock, #[case] base_block: ActiveRadarrBlock,
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(base_block.into()); app.push_navigation_stack(base_block.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
DownloadsHandler::with(ESC_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(ESC_KEY, &mut app, prompt_block, None).handle();
assert_eq!(app.get_current_route(), base_block.into()); assert_eq!(app.get_current_route(), base_block.into());
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
@@ -223,13 +224,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
DownloadsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle(); DownloadsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::Downloads, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Downloads.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Downloads.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -246,14 +247,14 @@ mod tests {
#[test] #[test]
fn test_update_downloads_key() { fn test_update_downloads_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -269,7 +270,7 @@ mod tests {
#[test] #[test]
fn test_update_downloads_key_no_op_when_not_ready() { fn test_update_downloads_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app app
@@ -278,7 +279,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -291,7 +292,7 @@ mod tests {
#[test] #[test]
fn test_refresh_downloads_key() { fn test_refresh_downloads_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -299,7 +300,7 @@ mod tests {
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -313,7 +314,7 @@ mod tests {
#[test] #[test]
fn test_refresh_downloads_key_no_op_when_not_ready() { fn test_refresh_downloads_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Downloads.into()); app.push_navigation_stack(ActiveRadarrBlock::Downloads.into());
app app
@@ -322,7 +323,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -350,7 +351,7 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -359,7 +360,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
prompt_block, prompt_block,
@@ -387,16 +388,32 @@ mod tests {
}) })
} }
#[rstest]
fn test_downloads_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_download_id() { fn test_extract_download_id() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.downloads .downloads
.set_items(vec![download_record()]); .set_items(vec![download_record()]);
let download_id = DownloadsHandler::with( let download_id = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -409,10 +426,10 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_not_ready_when_loading() { fn test_downloads_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -424,10 +441,10 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_not_ready_when_downloads_is_empty() { fn test_downloads_handler_not_ready_when_downloads_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
@@ -439,7 +456,7 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_ready_when_not_loading_and_downloads_is_not_empty() { fn test_downloads_handler_ready_when_not_loading_and_downloads_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
@@ -447,7 +464,7 @@ mod tests {
.radarr_data .radarr_data
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Downloads, ActiveRadarrBlock::Downloads,
+11 -8
View File
@@ -1,13 +1,12 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
use crate::models::radarr_models::DownloadRecord; use crate::models::radarr_models::DownloadRecord;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DOWNLOADS_BLOCKS};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "downloads_handler_tests.rs"] #[path = "downloads_handler_tests.rs"]
@@ -20,7 +19,7 @@ pub(super) struct DownloadsHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> DownloadsHandler<'a, 'b> { impl DownloadsHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
downloads, downloads,
@@ -47,7 +46,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
DOWNLOADS_BLOCKS.contains(&active_block) DOWNLOADS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -130,18 +133,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Downloads => match self.key { ActiveRadarrBlock::Downloads => match self.key {
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::UpdateDownloadsPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::UpdateDownloadsPrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::DeleteDownloadPrompt => { ActiveRadarrBlock::DeleteDownloadPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::DeleteDownload(self.extract_download_id())); Some(RadarrEvent::DeleteDownload(self.extract_download_id()));
@@ -150,7 +153,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DownloadsHandler<'a,
} }
} }
ActiveRadarrBlock::UpdateDownloadsPrompt => { ActiveRadarrBlock::UpdateDownloadsPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateDownloads); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateDownloads);
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -6,7 +5,9 @@ use crate::models::servarr_data::modals::EditIndexerModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS};
use crate::models::servarr_models::EditIndexerParams; use crate::models::servarr_models::EditIndexerParams;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{
handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
};
#[cfg(test)] #[cfg(test)]
#[path = "edit_indexer_handler_tests.rs"] #[path = "edit_indexer_handler_tests.rs"]
@@ -19,58 +20,44 @@ pub(super) struct EditIndexerHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> EditIndexerHandler<'a, 'b> { impl EditIndexerHandler<'_, '_> {
fn build_edit_indexer_params(&mut self) -> EditIndexerParams { fn build_edit_indexer_params(&mut self) -> EditIndexerParams {
let indexer_id = self.app.data.radarr_data.indexers.current_selection().id; let edit_indexer_modal = self
let tags = self
.app .app
.data .data
.radarr_data .radarr_data
.edit_indexer_modal .edit_indexer_modal
.as_ref() .take()
.unwrap() .expect("Edit Indexer Modal is None");
.tags let indexer_id = self.app.data.radarr_data.indexers.current_selection().id;
.text let tags = edit_indexer_modal.tags.text;
.clone();
let params = { let EditIndexerModal {
let EditIndexerModal { name,
name, enable_rss,
enable_rss, enable_automatic_search,
enable_automatic_search, enable_interactive_search,
enable_interactive_search, url,
url, api_key,
api_key, seed_ratio,
seed_ratio, priority,
priority, ..
.. } = edit_indexer_modal;
} = self
.app
.data
.radarr_data
.edit_indexer_modal
.as_ref()
.unwrap();
EditIndexerParams { EditIndexerParams {
indexer_id, indexer_id,
name: Some(name.text.clone()), name: Some(name.text),
enable_rss: Some(enable_rss.unwrap_or_default()), enable_rss: Some(enable_rss.unwrap_or_default()),
enable_automatic_search: Some(enable_automatic_search.unwrap_or_default()), enable_automatic_search: Some(enable_automatic_search.unwrap_or_default()),
enable_interactive_search: Some(enable_interactive_search.unwrap_or_default()), enable_interactive_search: Some(enable_interactive_search.unwrap_or_default()),
url: Some(url.text.clone()), url: Some(url.text),
api_key: Some(api_key.text.clone()), api_key: Some(api_key.text),
seed_ratio: Some(seed_ratio.text.clone()), seed_ratio: Some(seed_ratio.text),
tags: None, tags: None,
tag_input_string: Some(tags), tag_input_string: Some(tags),
priority: Some(*priority), priority: Some(priority),
clear_tags: false, clear_tags: false,
} }
};
self.app.data.radarr_data.edit_indexer_modal = None;
params
} }
} }
@@ -79,7 +66,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditIndexerHandler<'
EDIT_INDEXER_BLOCKS.contains(&active_block) EDIT_INDEXER_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -518,7 +509,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditIndexerHandler<'
ActiveRadarrBlock::EditIndexerPrompt => { ActiveRadarrBlock::EditIndexerPrompt => {
if self.app.data.radarr_data.selected_block.get_active_block() if self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::EditIndexerConfirmPrompt == ActiveRadarrBlock::EditIndexerConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
@@ -10,6 +10,7 @@ mod tests {
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_INDEXER_BLOCKS};
use crate::models::servarr_models::EditIndexerParams; use crate::models::servarr_models::EditIndexerParams;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
mod test_handle_scroll_up_and_down { mod test_handle_scroll_up_and_down {
@@ -25,11 +26,11 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_priority_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_priority_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPriorityInput, ActiveRadarrBlock::EditIndexerPriorityInput,
@@ -60,7 +61,7 @@ mod tests {
0 0
); );
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Up, Key::Up,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPriorityInput, ActiveRadarrBlock::EditIndexerPriorityInput,
@@ -79,7 +80,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPriorityInput, ActiveRadarrBlock::EditIndexerPriorityInput,
@@ -101,14 +102,14 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
if key == Key::Up { if key == Key::Up {
assert_eq!( assert_eq!(
@@ -127,7 +128,7 @@ mod tests {
fn test_edit_indexer_prompt_scroll_no_op_when_not_ready( fn test_edit_indexer_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
@@ -135,7 +136,7 @@ mod tests {
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -155,14 +156,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_home_end() { fn test_edit_indexer_name_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -183,7 +184,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -207,14 +208,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_home_end() { fn test_edit_indexer_url_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -235,7 +236,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -259,14 +260,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_home_end() { fn test_edit_indexer_api_key_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -287,7 +288,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -311,14 +312,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_home_end() { fn test_edit_indexer_seed_ratio_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -339,7 +340,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -363,14 +364,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_home_end() { fn test_edit_indexer_tags_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -391,7 +392,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -430,17 +431,17 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.y = EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1; app.data.radarr_data.selected_block.y = EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1;
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -472,7 +473,7 @@ mod tests {
#[case] left_block: ActiveRadarrBlock, #[case] left_block: ActiveRadarrBlock,
#[case] right_block: ActiveRadarrBlock, #[case] right_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
@@ -483,14 +484,14 @@ mod tests {
left_block left_block
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
right_block right_block
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -525,7 +526,7 @@ mod tests {
#[case] left_block: ActiveRadarrBlock, #[case] left_block: ActiveRadarrBlock,
#[case] right_block: ActiveRadarrBlock, #[case] right_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS);
@@ -536,14 +537,14 @@ mod tests {
left_block left_block
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
right_block right_block
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -555,7 +556,7 @@ mod tests {
fn test_left_right_block_toggle_torren_empty_row_to_prompt_confirm( fn test_left_right_block_toggle_torren_empty_row_to_prompt_confirm(
#[values(Key::Left, Key::Right)] key: Key, #[values(Key::Left, Key::Right)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
@@ -567,14 +568,14 @@ mod tests {
ActiveRadarrBlock::EditIndexerPriorityInput ActiveRadarrBlock::EditIndexerPriorityInput
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
ActiveRadarrBlock::EditIndexerConfirmPrompt ActiveRadarrBlock::EditIndexerConfirmPrompt
); );
EditIndexerHandler::with(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveRadarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -585,14 +586,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_left_right_keys() { fn test_edit_indexer_name_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -613,7 +614,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -637,14 +638,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_left_right_keys() { fn test_edit_indexer_url_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -665,7 +666,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -689,14 +690,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_left_right_keys() { fn test_edit_indexer_api_key_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -717,7 +718,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -741,14 +742,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_left_right_keys() { fn test_edit_indexer_seed_ratio_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -769,7 +770,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -793,14 +794,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_left_right_keys() { fn test_edit_indexer_tags_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -821,7 +822,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -861,7 +862,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_decline_submit() { fn test_edit_indexer_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -873,7 +874,7 @@ mod tests {
.set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1);
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -889,7 +890,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_submit() { fn test_edit_indexer_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -927,7 +928,7 @@ mod tests {
}; };
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -946,14 +947,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_indexer_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -981,7 +982,7 @@ mod tests {
#[case] starting_x: usize, #[case] starting_x: usize,
#[case] block: ActiveRadarrBlock, #[case] block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
@@ -993,7 +994,7 @@ mod tests {
.selected_block .selected_block
.set_index(starting_x, starting_y); .set_index(starting_x, starting_y);
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1007,7 +1008,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_priority_input_submit() { fn test_edit_indexer_priority_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
@@ -1015,7 +1016,7 @@ mod tests {
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, 4); app.data.radarr_data.selected_block.set_index(0, 4);
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1032,7 +1033,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_rss_submit() { fn test_edit_indexer_toggle_enable_rss_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -1040,7 +1041,7 @@ mod tests {
app.data.radarr_data.selected_block.set_index(0, 1); app.data.radarr_data.selected_block.set_index(0, 1);
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1061,7 +1062,7 @@ mod tests {
.enable_rss .enable_rss
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1085,7 +1086,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_automatic_search_submit() { fn test_edit_indexer_toggle_enable_automatic_search_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -1093,7 +1094,7 @@ mod tests {
app.data.radarr_data.selected_block.set_index(0, 2); app.data.radarr_data.selected_block.set_index(0, 2);
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1114,7 +1115,7 @@ mod tests {
.enable_automatic_search .enable_automatic_search
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1138,7 +1139,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_interactive_search_submit() { fn test_edit_indexer_toggle_enable_interactive_search_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -1146,7 +1147,7 @@ mod tests {
app.data.radarr_data.selected_block.set_index(0, 3); app.data.radarr_data.selected_block.set_index(0, 3);
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1167,7 +1168,7 @@ mod tests {
.enable_interactive_search .enable_interactive_search
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1191,7 +1192,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_submit() { fn test_edit_indexer_name_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1201,7 +1202,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerNameInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerNameInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -1227,7 +1228,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_submit() { fn test_edit_indexer_url_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1237,7 +1238,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerUrlInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerUrlInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -1263,7 +1264,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_submit() { fn test_edit_indexer_api_key_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1273,7 +1274,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerApiKeyInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerApiKeyInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -1299,7 +1300,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_submit() { fn test_edit_indexer_seed_ratio_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1309,7 +1310,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerSeedRatioInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerSeedRatioInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -1335,7 +1336,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_submit() { fn test_edit_indexer_tags_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1345,7 +1346,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerTagsInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerTagsInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -1382,13 +1383,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_prompt_esc(#[values(true, false)] is_ready: bool) { fn test_edit_indexer_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1413,13 +1414,13 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
EditIndexerHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); EditIndexerHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
assert!(!app.should_ignore_quit_key); assert!(!app.should_ignore_quit_key);
@@ -1442,14 +1443,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_backspace() { fn test_edit_indexer_name_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
@@ -1472,14 +1473,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_backspace() { fn test_edit_indexer_url_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
@@ -1502,14 +1503,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_backspace() { fn test_edit_indexer_api_key_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
@@ -1532,14 +1533,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_backspace() { fn test_edit_indexer_seed_ratio_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
@@ -1562,14 +1563,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_backspace() { fn test_edit_indexer_tags_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
@@ -1592,12 +1593,12 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_char_key() { fn test_edit_indexer_name_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerNameInput, ActiveRadarrBlock::EditIndexerNameInput,
None, None,
@@ -1613,18 +1614,18 @@ mod tests {
.unwrap() .unwrap()
.name .name
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_url_input_char_key() { fn test_edit_indexer_url_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerUrlInput, ActiveRadarrBlock::EditIndexerUrlInput,
None, None,
@@ -1640,18 +1641,18 @@ mod tests {
.unwrap() .unwrap()
.url .url
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_api_key_input_char_key() { fn test_edit_indexer_api_key_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerApiKeyInput, ActiveRadarrBlock::EditIndexerApiKeyInput,
None, None,
@@ -1667,18 +1668,18 @@ mod tests {
.unwrap() .unwrap()
.api_key .api_key
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_char_key() { fn test_edit_indexer_seed_ratio_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerSeedRatioInput, ActiveRadarrBlock::EditIndexerSeedRatioInput,
None, None,
@@ -1694,18 +1695,18 @@ mod tests {
.unwrap() .unwrap()
.seed_ratio .seed_ratio
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_tags_input_char_key() { fn test_edit_indexer_tags_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerTagsInput, ActiveRadarrBlock::EditIndexerTagsInput,
None, None,
@@ -1721,13 +1722,13 @@ mod tests {
.unwrap() .unwrap()
.tags .tags
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_confirm() { fn test_edit_indexer_prompt_prompt_confirmation_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditIndexerPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -1764,7 +1765,7 @@ mod tests {
..EditIndexerParams::default() ..EditIndexerParams::default()
}; };
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1793,9 +1794,25 @@ mod tests {
}) })
} }
#[rstest]
fn test_edit_indexer_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_indexer_params() { fn test_build_edit_indexer_params() {
let mut app = App::default(); let mut app = App::test_default();
let edit_indexer_modal = EditIndexerModal { let edit_indexer_modal = EditIndexerModal {
name: "Test Update".into(), name: "Test Update".into(),
enable_rss: Some(false), enable_rss: Some(false),
@@ -1823,7 +1840,7 @@ mod tests {
..EditIndexerParams::default() ..EditIndexerParams::default()
}; };
let edit_indexer_params = EditIndexerHandler::with( let edit_indexer_params = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1837,11 +1854,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_not_ready_when_loading() { fn test_edit_indexer_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1853,11 +1870,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_not_ready_when_edit_indexer_modal_is_none() { fn test_edit_indexer_handler_is_not_ready_when_edit_indexer_modal_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1869,12 +1886,12 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_ready_when_edit_indexer_modal_is_some() { fn test_edit_indexer_handler_is_ready_when_edit_indexer_modal_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.radarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditIndexerPrompt, ActiveRadarrBlock::EditIndexerPrompt,
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -7,7 +6,9 @@ use crate::models::servarr_data::radarr::radarr_data::{
ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS, ActiveRadarrBlock, INDEXER_SETTINGS_BLOCKS,
}; };
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{
handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
};
#[cfg(test)] #[cfg(test)]
#[path = "edit_indexer_settings_handler_tests.rs"] #[path = "edit_indexer_settings_handler_tests.rs"]
@@ -20,11 +21,15 @@ pub(super) struct IndexerSettingsHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> IndexerSettingsHandler<'a, 'b> { impl IndexerSettingsHandler<'_, '_> {
fn build_edit_indexer_settings_body(&mut self) -> IndexerSettings { fn build_edit_indexer_settings_body(&mut self) -> IndexerSettings {
let indexer_settings = self.app.data.radarr_data.indexer_settings.clone().unwrap(); self
self.app.data.radarr_data.indexer_settings = None; .app
indexer_settings .data
.radarr_data
.indexer_settings
.take()
.expect("Indexer settings not found")
} }
} }
@@ -33,7 +38,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexerSettingsHandl
INDEXER_SETTINGS_BLOCKS.contains(&active_block) INDEXER_SETTINGS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -265,7 +274,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexerSettingsHandl
ActiveRadarrBlock::AllIndexerSettingsPrompt => { ActiveRadarrBlock::AllIndexerSettingsPrompt => {
if self.app.data.radarr_data.selected_block.get_active_block() if self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::IndexerSettingsConfirmPrompt == ActiveRadarrBlock::IndexerSettingsConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some( self.app.data.radarr_data.prompt_confirm_action = Some(
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -26,10 +27,10 @@ mod tests {
macro_rules! test_i64_counter_scroll_value { macro_rules! test_i64_counter_scroll_value {
($block:expr, $key:expr, $data_ref:ident, $negatives:literal) => { ($block:expr, $key:expr, $data_ref:ident, $negatives:literal) => {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with($key, &mut app, $block, None).handle(); IndexerSettingsHandler::new($key, &mut app, $block, None).handle();
if $key == Key::Up { if $key == Key::Up {
assert_eq!( assert_eq!(
@@ -66,7 +67,7 @@ mod tests {
0 0
); );
IndexerSettingsHandler::with(Key::Up, &mut app, $block, None).handle(); IndexerSettingsHandler::new(Key::Up, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app app
@@ -79,7 +80,7 @@ mod tests {
1 1
); );
IndexerSettingsHandler::with($key, &mut app, $block, None).handle(); IndexerSettingsHandler::new($key, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app app
.data .data
@@ -97,13 +98,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_settings_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_settings_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -128,14 +129,14 @@ mod tests {
fn test_edit_indexer_settings_prompt_scroll_no_op_when_not_ready( fn test_edit_indexer_settings_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -213,13 +214,13 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whiteliested_subtitle_tags_input_home_end() { fn test_edit_indexer_settings_whiteliested_subtitle_tags_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings { app.data.radarr_data.indexer_settings = Some(IndexerSettings {
whitelisted_hardcoded_subs: "Test".into(), whitelisted_hardcoded_subs: "Test".into(),
..IndexerSettings::default() ..IndexerSettings::default()
}); });
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -240,7 +241,7 @@ mod tests {
4 4
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -276,12 +277,12 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.y = INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1; app.data.radarr_data.selected_block.y = INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -291,7 +292,7 @@ mod tests {
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -329,7 +330,7 @@ mod tests {
#[case] left_block: ActiveRadarrBlock, #[case] left_block: ActiveRadarrBlock,
#[case] right_block: ActiveRadarrBlock, #[case] right_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.y = starting_y_index; app.data.radarr_data.selected_block.y = starting_y_index;
@@ -339,7 +340,7 @@ mod tests {
left_block left_block
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -352,7 +353,7 @@ mod tests {
right_block right_block
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -368,13 +369,13 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_left_right_keys() { fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings { app.data.radarr_data.indexer_settings = Some(IndexerSettings {
whitelisted_hardcoded_subs: "Test".into(), whitelisted_hardcoded_subs: "Test".into(),
..IndexerSettings::default() ..IndexerSettings::default()
}); });
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -395,7 +396,7 @@ mod tests {
1 1
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -436,7 +437,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_decline_submit() { fn test_edit_indexer_settings_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -448,7 +449,7 @@ mod tests {
.set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1); .set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1);
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -464,7 +465,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_submit() { fn test_edit_indexer_settings_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -477,7 +478,7 @@ mod tests {
app.data.radarr_data.indexer_settings = Some(indexer_settings()); app.data.radarr_data.indexer_settings = Some(indexer_settings());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -496,14 +497,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_indexer_settings_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -529,7 +530,7 @@ mod tests {
#[case] y_index: usize, #[case] y_index: usize,
#[case] x_index: usize, #[case] x_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -540,7 +541,7 @@ mod tests {
.selected_block .selected_block
.set_index(x_index, y_index); .set_index(x_index, y_index);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -555,7 +556,7 @@ mod tests {
fn test_edit_indexer_settings_prompt_submit_selected_block_no_op_when_not_ready( fn test_edit_indexer_settings_prompt_submit_selected_block_no_op_when_not_ready(
#[values((0, 0), (1, 0), (2, 0), (0, 1), (1, 1))] index: (usize, usize), #[values((0, 0), (1, 0), (2, 0), (0, 1), (1, 1))] index: (usize, usize),
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
@@ -567,7 +568,7 @@ mod tests {
.selected_block .selected_block
.set_index(index.1, index.0); .set_index(index.1, index.0);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -583,14 +584,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_submit_whitelisted_subtitle_tags_input() { fn test_edit_indexer_settings_prompt_submit_whitelisted_subtitle_tags_input() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(1, 2); app.data.radarr_data.selected_block.set_index(1, 2);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -607,14 +608,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_toggle_prefer_indexer_flags_submit() { fn test_edit_indexer_settings_toggle_prefer_indexer_flags_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, 3); app.data.radarr_data.selected_block.set_index(0, 3);
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -636,7 +637,7 @@ mod tests {
.prefer_indexer_flags .prefer_indexer_flags
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -661,14 +662,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_toggle_allow_hardcoded_subs_submit() { fn test_edit_indexer_settings_toggle_allow_hardcoded_subs_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(1, 3); app.data.radarr_data.selected_block.set_index(1, 3);
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -690,7 +691,7 @@ mod tests {
.allow_hardcoded_subs .allow_hardcoded_subs
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -715,7 +716,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_submit() { fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.indexer_settings = Some(IndexerSettings { app.data.radarr_data.indexer_settings = Some(IndexerSettings {
whitelisted_hardcoded_subs: "Test tags".into(), whitelisted_hardcoded_subs: "Test tags".into(),
@@ -726,7 +727,7 @@ mod tests {
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput.into(), ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput.into(),
); );
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -761,12 +762,12 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
IndexerSettingsHandler::with(SUBMIT_KEY, &mut app, active_radarr_block, None).handle(); IndexerSettingsHandler::new(SUBMIT_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -787,13 +788,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_settings_prompt_esc(#[values(true, false)] is_ready: bool) { fn test_edit_indexer_settings_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -808,7 +809,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_esc() { fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack( app.push_navigation_stack(
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput.into(), ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput.into(),
@@ -816,7 +817,7 @@ mod tests {
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -844,12 +845,12 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); IndexerSettingsHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
assert_eq!( assert_eq!(
@@ -874,13 +875,13 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_backspace() { fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings { app.data.radarr_data.indexer_settings = Some(IndexerSettings {
whitelisted_hardcoded_subs: "Test".into(), whitelisted_hardcoded_subs: "Test".into(),
..IndexerSettings::default() ..IndexerSettings::default()
}); });
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
@@ -903,11 +904,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_char_key() { fn test_edit_indexer_settings_whitelisted_subtitle_tags_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput, ActiveRadarrBlock::IndexerSettingsWhitelistedSubtitleTagsInput,
None, None,
@@ -923,13 +924,13 @@ mod tests {
.unwrap() .unwrap()
.whitelisted_hardcoded_subs .whitelisted_hardcoded_subs
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_confirm() { fn test_edit_indexer_settings_prompt_prompt_confirmation_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
app.data.radarr_data.selected_block = app.data.radarr_data.selected_block =
@@ -941,7 +942,7 @@ mod tests {
.set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1); .set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1);
app.data.radarr_data.indexer_settings = Some(indexer_settings()); app.data.radarr_data.indexer_settings = Some(indexer_settings());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -970,12 +971,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_indexer_settings_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_indexer_settings_body() { fn test_build_edit_indexer_settings_body() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexer_settings = Some(indexer_settings()); app.data.radarr_data.indexer_settings = Some(indexer_settings());
let body = IndexerSettingsHandler::with( let body = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -989,10 +1006,10 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_not_ready_when_loading() { fn test_edit_indexer_settings_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -1004,10 +1021,10 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_not_ready_when_indexer_settings_is_none() { fn test_edit_indexer_settings_handler_not_ready_when_indexer_settings_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -1019,11 +1036,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_ready_when_not_loading_and_indexer_settings_is_some() { fn test_edit_indexer_settings_handler_ready_when_not_loading_and_indexer_settings_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.radarr_data.indexer_settings = Some(IndexerSettings::default());
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AllIndexerSettingsPrompt, ActiveRadarrBlock::AllIndexerSettingsPrompt,
@@ -25,14 +25,14 @@ mod tests {
#[test] #[test]
fn test_delete_indexer_prompt() { fn test_delete_indexer_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle(); IndexersHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -42,7 +42,7 @@ mod tests {
#[test] #[test]
fn test_delete_indexer_prompt_no_op_when_not_ready() { fn test_delete_indexer_prompt_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app app
@@ -51,7 +51,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle(); IndexersHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
} }
@@ -65,11 +65,11 @@ mod tests {
#[rstest] #[rstest]
fn test_indexers_tab_left(#[values(true, false)] is_ready: bool) { fn test_indexers_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(5); app.data.radarr_data.main_tabs.set_index(5);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -89,11 +89,11 @@ mod tests {
#[rstest] #[rstest]
fn test_indexers_tab_right(#[values(true, false)] is_ready: bool) { fn test_indexers_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(5); app.data.radarr_data.main_tabs.set_index(5);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -112,13 +112,13 @@ mod tests {
fn test_left_right_delete_indexer_prompt_toggle( fn test_left_right_delete_indexer_prompt_toggle(
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
IndexersHandler::with(key, &mut app, ActiveRadarrBlock::DeleteIndexerPrompt, None).handle(); IndexersHandler::new(key, &mut app, ActiveRadarrBlock::DeleteIndexerPrompt, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
IndexersHandler::with(key, &mut app, ActiveRadarrBlock::DeleteIndexerPrompt, None).handle(); IndexersHandler::new(key, &mut app, ActiveRadarrBlock::DeleteIndexerPrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -142,7 +142,7 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_submit(#[values(true, false)] torrent_protocol: bool) { fn test_edit_indexer_submit(#[values(true, false)] torrent_protocol: bool) {
let mut app = App::default(); let mut app = App::test_default();
let protocol = if torrent_protocol { let protocol = if torrent_protocol {
"torrent".to_owned() "torrent".to_owned()
} else { } else {
@@ -194,7 +194,7 @@ mod tests {
radarr_data.indexers.set_items(vec![indexer]); radarr_data.indexers.set_items(vec![indexer]);
app.data.radarr_data = radarr_data; app.data.radarr_data = radarr_data;
IndexersHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle(); IndexersHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -223,7 +223,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_submit_no_op_when_not_ready() { fn test_edit_indexer_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app app
@@ -232,7 +232,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle(); IndexersHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
assert_eq!(app.data.radarr_data.edit_indexer_modal, None); assert_eq!(app.data.radarr_data.edit_indexer_modal, None);
@@ -240,13 +240,13 @@ mod tests {
#[test] #[test]
fn test_delete_indexer_prompt_confirm_submit() { fn test_delete_indexer_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexers.set_items(vec![indexer()]); app.data.radarr_data.indexers.set_items(vec![indexer()]);
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
IndexersHandler::with( IndexersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteIndexerPrompt, ActiveRadarrBlock::DeleteIndexerPrompt,
@@ -264,7 +264,7 @@ mod tests {
#[test] #[test]
fn test_prompt_decline_submit() { fn test_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -273,7 +273,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
IndexersHandler::with( IndexersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteIndexerPrompt, ActiveRadarrBlock::DeleteIndexerPrompt,
@@ -296,13 +296,13 @@ mod tests {
#[rstest] #[rstest]
fn test_delete_indexer_prompt_block_esc(#[values(true, false)] is_ready: bool) { fn test_delete_indexer_prompt_block_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
IndexersHandler::with( IndexersHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteIndexerPrompt, ActiveRadarrBlock::DeleteIndexerPrompt,
@@ -316,13 +316,13 @@ mod tests {
#[rstest] #[rstest]
fn test_test_indexer_esc(#[values(true, false)] is_ready: bool) { fn test_test_indexer_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.indexer_test_errors = Some("test result".to_owned()); app.data.radarr_data.indexer_test_errors = Some("test result".to_owned());
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into()); app.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into());
IndexersHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::TestIndexer, None).handle(); IndexersHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::TestIndexer, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
assert_eq!(app.data.radarr_data.indexer_test_errors, None); assert_eq!(app.data.radarr_data.indexer_test_errors, None);
@@ -330,13 +330,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
IndexersHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle(); IndexersHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::Indexers, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Indexers.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -355,7 +355,7 @@ mod tests {
#[test] #[test]
fn test_refresh_indexers_key() { fn test_refresh_indexers_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -363,7 +363,7 @@ mod tests {
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -377,7 +377,7 @@ mod tests {
#[test] #[test]
fn test_refresh_indexers_key_no_op_when_not_ready() { fn test_refresh_indexers_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app app
.data .data
@@ -386,7 +386,7 @@ mod tests {
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -400,14 +400,14 @@ mod tests {
#[test] #[test]
fn test_indexer_settings_key() { fn test_indexer_settings_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.settings.key, DEFAULT_KEYBINDINGS.settings.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -427,7 +427,7 @@ mod tests {
#[test] #[test]
fn test_indexer_settings_key_no_op_when_not_ready() { fn test_indexer_settings_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app app
@@ -436,7 +436,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.settings.key, DEFAULT_KEYBINDINGS.settings.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -449,14 +449,14 @@ mod tests {
#[test] #[test]
fn test_test_key() { fn test_test_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.test.key, DEFAULT_KEYBINDINGS.test.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -472,7 +472,7 @@ mod tests {
#[test] #[test]
fn test_test_key_no_op_when_not_ready() { fn test_test_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app app
@@ -481,7 +481,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.test.key, DEFAULT_KEYBINDINGS.test.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -494,14 +494,14 @@ mod tests {
#[test] #[test]
fn test_test_all_key() { fn test_test_all_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.test_all.key, DEFAULT_KEYBINDINGS.test_all.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -517,7 +517,7 @@ mod tests {
#[test] #[test]
fn test_test_all_key_no_op_when_not_ready() { fn test_test_all_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app app
@@ -526,7 +526,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.test_all.key, DEFAULT_KEYBINDINGS.test_all.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -539,12 +539,12 @@ mod tests {
#[test] #[test]
fn test_delete_indexer_prompt_confirm() { fn test_delete_indexer_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexers.set_items(vec![indexer()]); app.data.radarr_data.indexers.set_items(vec![indexer()]);
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteIndexerPrompt.into());
IndexersHandler::with( IndexersHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteIndexerPrompt, ActiveRadarrBlock::DeleteIndexerPrompt,
@@ -633,12 +633,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_indexers_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = IndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_indexer_id() { fn test_extract_indexer_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.indexers.set_items(vec![indexer()]); app.data.radarr_data.indexers.set_items(vec![indexer()]);
let indexer_id = IndexersHandler::with( let indexer_id = IndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -651,10 +667,10 @@ mod tests {
#[test] #[test]
fn test_indexers_handler_not_ready_when_loading() { fn test_indexers_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = IndexersHandler::with( let handler = IndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -666,10 +682,10 @@ mod tests {
#[test] #[test]
fn test_indexers_handler_not_ready_when_indexers_is_empty() { fn test_indexers_handler_not_ready_when_indexers_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = IndexersHandler::with( let handler = IndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
@@ -681,7 +697,7 @@ mod tests {
#[test] #[test]
fn test_indexers_handler_ready_when_not_loading_and_indexers_is_not_empty() { fn test_indexers_handler_ready_when_not_loading_and_indexers_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -689,7 +705,7 @@ mod tests {
.indexers .indexers
.set_items(vec![Indexer::default()]); .set_items(vec![Indexer::default()]);
let handler = IndexersHandler::with( let handler = IndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Indexers,
+15 -12
View File
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::radarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler; use crate::handlers::radarr_handlers::indexers::edit_indexer_handler::EditIndexerHandler;
use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler; use crate::handlers::radarr_handlers::indexers::edit_indexer_settings_handler::IndexerSettingsHandler;
@@ -15,6 +13,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
use crate::models::servarr_models::Indexer; use crate::models::servarr_models::Indexer;
use crate::models::BlockSelectionState; use crate::models::BlockSelectionState;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
mod edit_indexer_handler; mod edit_indexer_handler;
mod edit_indexer_settings_handler; mod edit_indexer_settings_handler;
@@ -31,7 +30,7 @@ pub(super) struct IndexersHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> IndexersHandler<'a, 'b> { impl IndexersHandler<'_, '_> {
handle_table_events!(self, indexers, self.app.data.radarr_data.indexers, Indexer); handle_table_events!(self, indexers, self.app.data.radarr_data.indexers, Indexer);
fn extract_indexer_id(&self) -> i64 { fn extract_indexer_id(&self) -> i64 {
@@ -47,15 +46,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
if !self.handle_indexers_table_events(indexer_table_handling_config) { if !self.handle_indexers_table_events(indexer_table_handling_config) {
match self.active_radarr_block { match self.active_radarr_block {
_ if EditIndexerHandler::accepts(self.active_radarr_block) => { _ if EditIndexerHandler::accepts(self.active_radarr_block) => {
EditIndexerHandler::with(self.key, self.app, self.active_radarr_block, self.context) EditIndexerHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle() .handle()
} }
_ if IndexerSettingsHandler::accepts(self.active_radarr_block) => { _ if IndexerSettingsHandler::accepts(self.active_radarr_block) => {
IndexerSettingsHandler::with(self.key, self.app, self.active_radarr_block, self.context) IndexerSettingsHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle() .handle()
} }
_ if TestAllIndexersHandler::accepts(self.active_radarr_block) => { _ if TestAllIndexersHandler::accepts(self.active_radarr_block) => {
TestAllIndexersHandler::with(self.key, self.app, self.active_radarr_block, self.context) TestAllIndexersHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle() .handle()
} }
_ => self.handle_key_event(), _ => self.handle_key_event(),
@@ -70,7 +69,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
|| INDEXERS_BLOCKS.contains(&active_block) || INDEXERS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -169,20 +172,20 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Indexers => match self.key { ActiveRadarrBlock::Indexers => match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ if key == DEFAULT_KEYBINDINGS.test.key => { _ if matches_key!(test, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::TestIndexer.into()); .push_navigation_stack(ActiveRadarrBlock::TestIndexer.into());
} }
_ if key == DEFAULT_KEYBINDINGS.test_all.key => { _ if matches_key!(test_all, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into()); .push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into());
} }
_ if key == DEFAULT_KEYBINDINGS.settings.key => { _ if matches_key!(settings, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::AllIndexerSettingsPrompt.into());
@@ -192,7 +195,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for IndexersHandler<'a,
_ => (), _ => (),
}, },
ActiveRadarrBlock::DeleteIndexerPrompt => { ActiveRadarrBlock::DeleteIndexerPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::DeleteIndexer(self.extract_indexer_id())); Some(RadarrEvent::DeleteIndexer(self.extract_indexer_id()));
@@ -17,7 +17,7 @@ pub(super) struct TestAllIndexersHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> TestAllIndexersHandler<'a, 'b> { impl TestAllIndexersHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
indexer_test_all_results, indexer_test_all_results,
@@ -48,7 +48,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for TestAllIndexersHandl
active_block == ActiveRadarrBlock::TestAllIndexers active_block == ActiveRadarrBlock::TestAllIndexers
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -7,6 +7,7 @@ mod tests {
use crate::models::servarr_data::modals::IndexerTestResultModalItem; use crate::models::servarr_data::modals::IndexerTestResultModalItem;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::stateful_table::StatefulTable; use crate::models::stateful_table::StatefulTable;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
mod test_handle_esc { mod test_handle_esc {
@@ -17,13 +18,13 @@ mod tests {
#[rstest] #[rstest]
fn test_test_all_indexers_esc(#[values(true, false)] is_ready: bool) { fn test_test_all_indexers_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Indexers.into()); app.push_navigation_stack(ActiveRadarrBlock::Indexers.into());
app.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into()); app.push_navigation_stack(ActiveRadarrBlock::TestAllIndexers.into());
app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default()); app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default());
TestAllIndexersHandler::with( TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::TestAllIndexers, ActiveRadarrBlock::TestAllIndexers,
@@ -48,12 +49,28 @@ mod tests {
}); });
} }
#[rstest]
fn test_test_all_indexers_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_test_all_indexers_handler_is_not_ready_when_loading() { fn test_test_all_indexers_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = TestAllIndexersHandler::with( let handler = TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::TestAllIndexers, ActiveRadarrBlock::TestAllIndexers,
@@ -65,10 +82,10 @@ mod tests {
#[test] #[test]
fn test_test_all_indexers_handler_is_not_ready_when_results_is_none() { fn test_test_all_indexers_handler_is_not_ready_when_results_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = TestAllIndexersHandler::with( let handler = TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::TestAllIndexers, ActiveRadarrBlock::TestAllIndexers,
@@ -80,11 +97,11 @@ mod tests {
#[test] #[test]
fn test_test_all_indexers_handler_is_not_ready_when_results_is_empty() { fn test_test_all_indexers_handler_is_not_ready_when_results_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default()); app.data.radarr_data.indexer_test_all_results = Some(StatefulTable::default());
let handler = TestAllIndexersHandler::with( let handler = TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::TestAllIndexers, ActiveRadarrBlock::TestAllIndexers,
@@ -96,13 +113,13 @@ mod tests {
#[test] #[test]
fn test_test_all_indexers_handler_is_ready_when_results_is_not_empty_and_is_loaded() { fn test_test_all_indexers_handler_is_ready_when_results_is_not_empty_and_is_loaded() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let mut indexer_test_results = StatefulTable::default(); let mut indexer_test_results = StatefulTable::default();
indexer_test_results.set_items(vec![IndexerTestResultModalItem::default()]); indexer_test_results.set_items(vec![IndexerTestResultModalItem::default()]);
app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results); app.data.radarr_data.indexer_test_all_results = Some(indexer_test_results);
let handler = TestAllIndexersHandler::with( let handler = TestAllIndexersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::TestAllIndexers, ActiveRadarrBlock::TestAllIndexers,
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::models::radarr_models::{ use crate::models::radarr_models::{
@@ -11,7 +10,9 @@ use crate::models::servarr_data::radarr::radarr_data::{
use crate::models::stateful_table::StatefulTable; use crate::models::stateful_table::StatefulTable;
use crate::models::{BlockSelectionState, Scrollable}; use crate::models::{BlockSelectionState, Scrollable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, App, Key}; use crate::{
handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, matches_key, App, Key,
};
#[cfg(test)] #[cfg(test)]
#[path = "add_movie_handler_tests.rs"] #[path = "add_movie_handler_tests.rs"]
@@ -24,7 +25,7 @@ pub(super) struct AddMovieHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> AddMovieHandler<'a, 'b> { impl AddMovieHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
add_movie_search_results, add_movie_search_results,
@@ -39,23 +40,21 @@ impl<'a, 'b> AddMovieHandler<'a, 'b> {
); );
fn build_add_movie_body(&mut self) -> AddMovieBody { fn build_add_movie_body(&mut self) -> AddMovieBody {
let tags = self let add_movie_modal = self
.app .app
.data .data
.radarr_data .radarr_data
.add_movie_modal .add_movie_modal
.as_ref() .take()
.unwrap() .expect("AddMovieModal is None");
.tags let tags = add_movie_modal.tags.text;
.text
.clone();
let AddMovieModal { let AddMovieModal {
root_folder_list, root_folder_list,
monitor_list, monitor_list,
minimum_availability_list, minimum_availability_list,
quality_profile_list, quality_profile_list,
.. ..
} = self.app.data.radarr_data.add_movie_modal.as_ref().unwrap(); } = add_movie_modal;
let (tmdb_id, title) = if let Some(context) = self.context { let (tmdb_id, title) = if let Some(context) = self.context {
if context == ActiveRadarrBlock::CollectionDetails { if context == ActiveRadarrBlock::CollectionDetails {
let CollectionMovie { tmdb_id, title, .. } = self let CollectionMovie { tmdb_id, title, .. } = self
@@ -63,9 +62,8 @@ impl<'a, 'b> AddMovieHandler<'a, 'b> {
.data .data
.radarr_data .radarr_data
.collection_movies .collection_movies
.current_selection() .current_selection();
.clone(); (*tmdb_id, title.clone().text)
(tmdb_id, title.text)
} else { } else {
let AddMovieSearchResult { tmdb_id, title, .. } = self let AddMovieSearchResult { tmdb_id, title, .. } = self
.app .app
@@ -74,9 +72,8 @@ impl<'a, 'b> AddMovieHandler<'a, 'b> {
.add_searched_movies .add_searched_movies
.as_ref() .as_ref()
.unwrap() .unwrap()
.current_selection() .current_selection();
.clone(); (*tmdb_id, title.clone().text)
(tmdb_id, title.text)
} }
} else { } else {
let AddMovieSearchResult { tmdb_id, title, .. } = self let AddMovieSearchResult { tmdb_id, title, .. } = self
@@ -86,9 +83,8 @@ impl<'a, 'b> AddMovieHandler<'a, 'b> {
.add_searched_movies .add_searched_movies
.as_ref() .as_ref()
.unwrap() .unwrap()
.current_selection() .current_selection();
.clone(); (*tmdb_id, title.clone().text)
(tmdb_id, title.text)
}; };
let quality_profile = quality_profile_list.current_selection(); let quality_profile = quality_profile_list.current_selection();
let quality_profile_id = *self let quality_profile_id = *self
@@ -106,8 +102,6 @@ impl<'a, 'b> AddMovieHandler<'a, 'b> {
let monitor = monitor_list.current_selection().to_string(); let monitor = monitor_list.current_selection().to_string();
let minimum_availability = minimum_availability_list.current_selection().to_string(); let minimum_availability = minimum_availability_list.current_selection().to_string();
self.app.data.radarr_data.add_movie_modal = None;
AddMovieBody { AddMovieBody {
tmdb_id, tmdb_id,
title, title,
@@ -139,7 +133,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
ADD_MOVIE_BLOCKS.contains(&active_block) ADD_MOVIE_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -549,7 +547,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for AddMovieHandler<'a,
ActiveRadarrBlock::AddMoviePrompt => { ActiveRadarrBlock::AddMoviePrompt => {
if self.app.data.radarr_data.selected_block.get_active_block() if self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::AddMovieConfirmPrompt == ActiveRadarrBlock::AddMovieConfirmPrompt
&& key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
@@ -37,7 +37,7 @@ mod tests {
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let monitor_vec = Vec::from_iter(MovieMonitor::iter()); let monitor_vec = Vec::from_iter(MovieMonitor::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -50,7 +50,7 @@ mod tests {
if key == Key::Up { if key == Key::Up {
for i in (0..monitor_vec.len()).rev() { for i in (0..monitor_vec.len()).rev() {
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMonitor, ActiveRadarrBlock::AddMovieSelectMonitor,
@@ -72,7 +72,7 @@ mod tests {
} }
} else { } else {
for i in 0..monitor_vec.len() { for i in 0..monitor_vec.len() {
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMonitor, ActiveRadarrBlock::AddMovieSelectMonitor,
@@ -100,7 +100,7 @@ mod tests {
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -113,7 +113,7 @@ mod tests {
if key == Key::Up { if key == Key::Up {
for i in (0..minimum_availability_vec.len()).rev() { for i in (0..minimum_availability_vec.len()).rev() {
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMinimumAvailability, ActiveRadarrBlock::AddMovieSelectMinimumAvailability,
@@ -135,7 +135,7 @@ mod tests {
} }
} else { } else {
for i in 0..minimum_availability_vec.len() { for i in 0..minimum_availability_vec.len() {
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMinimumAvailability, ActiveRadarrBlock::AddMovieSelectMinimumAvailability,
@@ -162,7 +162,7 @@ mod tests {
fn test_add_movie_select_quality_profile_scroll( fn test_add_movie_select_quality_profile_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -173,7 +173,7 @@ mod tests {
.quality_profile_list .quality_profile_list
.set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]);
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectQualityProfile, ActiveRadarrBlock::AddMovieSelectQualityProfile,
@@ -193,7 +193,7 @@ mod tests {
"Test 2" "Test 2"
); );
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectQualityProfile, ActiveRadarrBlock::AddMovieSelectQualityProfile,
@@ -218,7 +218,7 @@ mod tests {
fn test_add_movie_select_root_folder_scroll( fn test_add_movie_select_root_folder_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -229,7 +229,7 @@ mod tests {
.root_folder_list .root_folder_list
.set_items(simple_stateful_iterable_vec!(RootFolder, String, path)); .set_items(simple_stateful_iterable_vec!(RootFolder, String, path));
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectRootFolder, ActiveRadarrBlock::AddMovieSelectRootFolder,
@@ -250,7 +250,7 @@ mod tests {
"Test 2" "Test 2"
); );
AddMovieHandler::with( AddMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectRootFolder, ActiveRadarrBlock::AddMovieSelectRootFolder,
@@ -274,11 +274,11 @@ mod tests {
#[rstest] #[rstest]
fn test_add_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_add_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
AddMovieHandler::with(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle(); AddMovieHandler::new(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle();
if key == Key::Up { if key == Key::Up {
assert_eq!( assert_eq!(
@@ -295,12 +295,12 @@ mod tests {
#[rstest] #[rstest]
fn test_add_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) { fn test_add_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
AddMovieHandler::with(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle(); AddMovieHandler::new(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -322,7 +322,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_select_monitor_home_end() { fn test_add_movie_select_monitor_home_end() {
let monitor_vec = Vec::from_iter(MovieMonitor::iter()); let monitor_vec = Vec::from_iter(MovieMonitor::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -333,7 +333,7 @@ mod tests {
.monitor_list .monitor_list
.set_items(monitor_vec.clone()); .set_items(monitor_vec.clone());
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMonitor, ActiveRadarrBlock::AddMovieSelectMonitor,
@@ -353,7 +353,7 @@ mod tests {
&monitor_vec[monitor_vec.len() - 1] &monitor_vec[monitor_vec.len() - 1]
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMonitor, ActiveRadarrBlock::AddMovieSelectMonitor,
@@ -377,7 +377,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_select_minimum_availability_home_end() { fn test_add_movie_select_minimum_availability_home_end() {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -388,7 +388,7 @@ mod tests {
.minimum_availability_list .minimum_availability_list
.set_items(minimum_availability_vec.clone()); .set_items(minimum_availability_vec.clone());
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMinimumAvailability, ActiveRadarrBlock::AddMovieSelectMinimumAvailability,
@@ -408,7 +408,7 @@ mod tests {
&minimum_availability_vec[minimum_availability_vec.len() - 1] &minimum_availability_vec[minimum_availability_vec.len() - 1]
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectMinimumAvailability, ActiveRadarrBlock::AddMovieSelectMinimumAvailability,
@@ -431,7 +431,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_select_quality_profile_home_end() { fn test_add_movie_select_quality_profile_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -446,7 +446,7 @@ mod tests {
"Test 3".to_owned(), "Test 3".to_owned(),
]); ]);
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectQualityProfile, ActiveRadarrBlock::AddMovieSelectQualityProfile,
@@ -466,7 +466,7 @@ mod tests {
"Test 3" "Test 3"
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectQualityProfile, ActiveRadarrBlock::AddMovieSelectQualityProfile,
@@ -489,7 +489,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_select_root_folder_home_end() { fn test_add_movie_select_root_folder_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app app
.data .data
@@ -500,7 +500,7 @@ mod tests {
.root_folder_list .root_folder_list
.set_items(extended_stateful_iterable_vec!(RootFolder, String, path)); .set_items(extended_stateful_iterable_vec!(RootFolder, String, path));
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectRootFolder, ActiveRadarrBlock::AddMovieSelectRootFolder,
@@ -521,7 +521,7 @@ mod tests {
"Test 3" "Test 3"
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSelectRootFolder, ActiveRadarrBlock::AddMovieSelectRootFolder,
@@ -545,10 +545,10 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_input_home_end_keys() { fn test_add_movie_search_input_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_search = Some("Test".into()); app.data.radarr_data.add_movie_search = Some("Test".into());
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -568,7 +568,7 @@ mod tests {
4 4
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -591,13 +591,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_tags_input_home_end_keys() { fn test_add_movie_tags_input_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal { app.data.radarr_data.add_movie_modal = Some(AddMovieModal {
tags: "Test".into(), tags: "Test".into(),
..AddMovieModal::default() ..AddMovieModal::default()
}); });
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -618,7 +618,7 @@ mod tests {
4 4
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -651,23 +651,23 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
AddMovieHandler::with(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle(); AddMovieHandler::new(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
AddMovieHandler::with(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle(); AddMovieHandler::new(key, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
#[test] #[test]
fn test_add_movie_search_input_left_right_keys() { fn test_add_movie_search_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_search = Some("Test".into()); app.data.radarr_data.add_movie_search = Some("Test".into());
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -687,7 +687,7 @@ mod tests {
1 1
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -710,13 +710,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_tags_input_left_right_keys() { fn test_add_movie_tags_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal { app.data.radarr_data.add_movie_modal = Some(AddMovieModal {
tags: "Test".into(), tags: "Test".into(),
..AddMovieModal::default() ..AddMovieModal::default()
}); });
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -737,7 +737,7 @@ mod tests {
1 1
); );
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -781,11 +781,11 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_input_submit() { fn test_add_movie_search_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.add_movie_search = Some("test".into()); app.data.radarr_data.add_movie_search = Some("test".into());
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -802,12 +802,12 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_input_submit_noop_on_empty_search() { fn test_add_movie_search_input_submit_noop_on_empty_search() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default()); app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default());
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -824,14 +824,14 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit() { fn test_add_movie_search_results_submit() {
let mut app = App::default(); let mut app = App::test_default();
let mut add_searched_movies = StatefulTable::default(); let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]); add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies); app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
app.data.radarr_data.quality_profile_map = app.data.radarr_data.quality_profile_map =
BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]); BiMap::from_iter([(1, "B - Test 2".to_owned()), (0, "A - Test 1".to_owned())]);
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchResults, ActiveRadarrBlock::AddMovieSearchResults,
@@ -890,13 +890,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit_no_op_when_not_ready() { fn test_add_movie_search_results_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into());
let mut add_searched_movies = StatefulTable::default(); let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]); add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchResults, ActiveRadarrBlock::AddMovieSearchResults,
@@ -913,9 +913,9 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit_does_nothing_on_empty_table() { fn test_add_movie_search_results_submit_does_nothing_on_empty_table() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into());
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchResults, ActiveRadarrBlock::AddMovieSearchResults,
@@ -931,7 +931,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_results_submit_movie_already_in_library() { fn test_add_movie_search_results_submit_movie_already_in_library() {
let mut app = App::default(); let mut app = App::test_default();
let mut add_searched_movies = StatefulTable::default(); let mut add_searched_movies = StatefulTable::default();
add_searched_movies.set_items(vec![AddMovieSearchResult::default()]); add_searched_movies.set_items(vec![AddMovieSearchResult::default()]);
app.data.radarr_data.add_searched_movies = Some(add_searched_movies); app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
@@ -941,7 +941,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchResults, ActiveRadarrBlock::AddMovieSearchResults,
@@ -957,7 +957,7 @@ mod tests {
#[test] #[test]
fn test_add_movie_prompt_prompt_decline_submit() { fn test_add_movie_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS);
@@ -967,7 +967,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, ADD_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, ADD_MOVIE_SELECTION_BLOCKS.len() - 1);
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -983,7 +983,7 @@ mod tests {
fn test_add_movie_confirm_prompt_prompt_confirmation_submit( fn test_add_movie_confirm_prompt_prompt_confirmation_submit(
#[values(true, false)] movie_details_context: bool, #[values(true, false)] movie_details_context: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
@@ -1041,7 +1041,7 @@ mod tests {
None None
}; };
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1067,7 +1067,7 @@ mod tests {
#[case] selected_block: ActiveRadarrBlock, #[case] selected_block: ActiveRadarrBlock,
#[case] y_index: usize, #[case] y_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack( app.push_navigation_stack(
( (
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1078,7 +1078,7 @@ mod tests {
app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(ADD_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, y_index); app.data.radarr_data.selected_block.set_index(0, y_index);
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1108,11 +1108,11 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
AddMovieHandler::with( AddMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -1146,13 +1146,13 @@ mod tests {
#[rstest] #[rstest]
fn test_add_movie_search_input_esc(#[values(true, false)] is_ready: bool) { fn test_add_movie_search_input_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
AddMovieHandler::with( AddMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -1167,13 +1167,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_input_esc() { fn test_add_movie_input_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMovieTagsInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieTagsInput.into());
AddMovieHandler::with( AddMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -1196,7 +1196,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
let mut add_searched_movies = StatefulTable::default(); let mut add_searched_movies = StatefulTable::default();
@@ -1206,7 +1206,7 @@ mod tests {
)); ));
app.data.radarr_data.add_searched_movies = Some(add_searched_movies); app.data.radarr_data.add_searched_movies = Some(add_searched_movies);
AddMovieHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); AddMovieHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -1218,12 +1218,12 @@ mod tests {
#[test] #[test]
fn test_add_movie_already_in_library_esc() { fn test_add_movie_already_in_library_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMovieAlreadyInLibrary.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieAlreadyInLibrary.into());
AddMovieHandler::with( AddMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieAlreadyInLibrary, ActiveRadarrBlock::AddMovieAlreadyInLibrary,
@@ -1239,13 +1239,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_prompt_esc() { fn test_add_movie_prompt_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchResults.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
AddMovieHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle(); AddMovieHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::AddMoviePrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -1257,13 +1257,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_tags_input_esc() { fn test_add_movie_tags_input_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMovieTagsInput.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMovieTagsInput.into());
AddMovieHandler::with( AddMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -1288,7 +1288,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack( app.push_navigation_stack(
( (
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1304,7 +1304,7 @@ mod tests {
.into(), .into(),
); );
AddMovieHandler::with( AddMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -1343,10 +1343,10 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_input_backspace() { fn test_add_movie_search_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_search = Some("Test".into()); app.data.radarr_data.add_movie_search = Some("Test".into());
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
@@ -1362,13 +1362,13 @@ mod tests {
#[test] #[test]
fn test_add_movie_tags_input_backspace() { fn test_add_movie_tags_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal { app.data.radarr_data.add_movie_modal = Some(AddMovieModal {
tags: "Test".into(), tags: "Test".into(),
..AddMovieModal::default() ..AddMovieModal::default()
}); });
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
@@ -1391,11 +1391,11 @@ mod tests {
#[test] #[test]
fn test_add_movie_search_input_char_key() { fn test_add_movie_search_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default()); app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default());
AddMovieHandler::with( AddMovieHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchInput, ActiveRadarrBlock::AddMovieSearchInput,
None, None,
@@ -1404,17 +1404,17 @@ mod tests {
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.add_movie_search.as_ref().unwrap().text, app.data.radarr_data.add_movie_search.as_ref().unwrap().text,
"h" "a"
); );
} }
#[test] #[test]
fn test_add_movie_tags_input_char_key() { fn test_add_movie_tags_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
AddMovieHandler::with( AddMovieHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::AddMovieTagsInput, ActiveRadarrBlock::AddMovieTagsInput,
None, None,
@@ -1430,7 +1430,7 @@ mod tests {
.unwrap() .unwrap()
.tags .tags
.text, .text,
"h" "a"
); );
} }
@@ -1438,7 +1438,7 @@ mod tests {
fn test_add_movie_confirm_prompt_prompt_confirmation_confirm( fn test_add_movie_confirm_prompt_prompt_confirmation_confirm(
#[values(true, false)] movie_details_context: bool, #[values(true, false)] movie_details_context: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default()); app.data.radarr_data.add_movie_modal = Some(AddMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddMoviePrompt.into());
@@ -1495,7 +1495,7 @@ mod tests {
None None
}; };
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1523,12 +1523,28 @@ mod tests {
}); });
} }
#[rstest]
fn test_add_movie_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = AddMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_add_movie_search_no_panic_on_none_search_result() { fn test_add_movie_search_no_panic_on_none_search_result() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.add_searched_movies = None; app.data.radarr_data.add_searched_movies = None;
AddMovieHandler::with( AddMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMovieSearchResults, ActiveRadarrBlock::AddMovieSearchResults,
@@ -1539,7 +1555,7 @@ mod tests {
#[rstest] #[rstest]
fn test_build_add_movie_body(#[values(true, false)] movie_details_context: bool) { fn test_build_add_movie_body(#[values(true, false)] movie_details_context: bool) {
let mut app = App::default(); let mut app = App::test_default();
let mut add_movie_modal = AddMovieModal { let mut add_movie_modal = AddMovieModal {
tags: "usenet, testing".into(), tags: "usenet, testing".into(),
..AddMovieModal::default() ..AddMovieModal::default()
@@ -1586,7 +1602,7 @@ mod tests {
None None
}; };
let actual_add_movie_body = AddMovieHandler::with( let actual_add_movie_body = AddMovieHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1599,10 +1615,10 @@ mod tests {
#[test] #[test]
fn test_add_movie_handler_is_not_ready_when_loading() { fn test_add_movie_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = AddMovieHandler::with( let handler = AddMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1614,10 +1630,10 @@ mod tests {
#[test] #[test]
fn test_add_movie_handler_is_ready_when_not_loading() { fn test_add_movie_handler_is_ready_when_not_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = AddMovieHandler::with( let handler = AddMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AddMoviePrompt, ActiveRadarrBlock::AddMoviePrompt,
@@ -1,7 +1,7 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::matches_key;
use crate::models::radarr_models::DeleteMovieParams; use crate::models::radarr_models::DeleteMovieParams;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, DELETE_MOVIE_BLOCKS};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
@@ -17,7 +17,7 @@ pub(super) struct DeleteMovieHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> DeleteMovieHandler<'a, 'b> { impl DeleteMovieHandler<'_, '_> {
fn build_delete_movie_params(&mut self) -> DeleteMovieParams { fn build_delete_movie_params(&mut self) -> DeleteMovieParams {
let id = self.app.data.radarr_data.movies.current_selection().id; let id = self.app.data.radarr_data.movies.current_selection().id;
let delete_movie_files = self.app.data.radarr_data.delete_movie_files; let delete_movie_files = self.app.data.radarr_data.delete_movie_files;
@@ -37,7 +37,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
DELETE_MOVIE_BLOCKS.contains(&active_block) DELETE_MOVIE_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -122,7 +126,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for DeleteMovieHandler<'
if self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt if self.active_radarr_block == ActiveRadarrBlock::DeleteMoviePrompt
&& self.app.data.radarr_data.selected_block.get_active_block() && self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::DeleteMovieConfirmPrompt == ActiveRadarrBlock::DeleteMovieConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -23,11 +24,11 @@ mod tests {
#[rstest] #[rstest]
fn test_delete_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_delete_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
DeleteMovieHandler::with(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle(); DeleteMovieHandler::new(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle();
if key == Key::Up { if key == Key::Up {
assert_eq!( assert_eq!(
@@ -46,12 +47,12 @@ mod tests {
fn test_delete_movie_prompt_scroll_no_op_when_not_ready( fn test_delete_movie_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
DeleteMovieHandler::with(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle(); DeleteMovieHandler::new(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -67,13 +68,13 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
DeleteMovieHandler::with(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle(); DeleteMovieHandler::new(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
DeleteMovieHandler::with(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle(); DeleteMovieHandler::new(key, &mut app, ActiveRadarrBlock::DeleteMoviePrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -92,7 +93,7 @@ mod tests {
#[test] #[test]
fn test_delete_movie_prompt_prompt_decline_submit() { fn test_delete_movie_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS);
@@ -104,7 +105,7 @@ mod tests {
app.data.radarr_data.delete_movie_files = true; app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true; app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with( DeleteMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -121,7 +122,7 @@ mod tests {
#[test] #[test]
fn test_delete_movie_confirm_prompt_prompt_confirmation_submit() { fn test_delete_movie_confirm_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
let expected_delete_movie_params = DeleteMovieParams { let expected_delete_movie_params = DeleteMovieParams {
id: 1, id: 1,
delete_movie_files: true, delete_movie_files: true,
@@ -140,7 +141,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, DELETE_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, DELETE_MOVIE_SELECTION_BLOCKS.len() - 1);
DeleteMovieHandler::with( DeleteMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -161,7 +162,7 @@ mod tests {
#[test] #[test]
fn test_delete_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_delete_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
@@ -169,7 +170,7 @@ mod tests {
app.data.radarr_data.delete_movie_files = true; app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true; app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with( DeleteMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -191,11 +192,11 @@ mod tests {
#[test] #[test]
fn test_delete_movie_toggle_delete_files_submit() { fn test_delete_movie_toggle_delete_files_submit() {
let current_route = ActiveRadarrBlock::DeleteMoviePrompt.into(); let current_route = ActiveRadarrBlock::DeleteMoviePrompt.into();
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(DELETE_MOVIE_SELECTION_BLOCKS);
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
DeleteMovieHandler::with( DeleteMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -206,7 +207,7 @@ mod tests {
assert_eq!(app.get_current_route(), current_route); assert_eq!(app.get_current_route(), current_route);
assert_eq!(app.data.radarr_data.delete_movie_files, true); assert_eq!(app.data.radarr_data.delete_movie_files, true);
DeleteMovieHandler::with( DeleteMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -228,7 +229,7 @@ mod tests {
#[rstest] #[rstest]
fn test_delete_movie_prompt_esc(#[values(true, false)] is_ready: bool) { fn test_delete_movie_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteMoviePrompt.into());
@@ -236,7 +237,7 @@ mod tests {
app.data.radarr_data.delete_movie_files = true; app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true; app.data.radarr_data.add_list_exclusion = true;
DeleteMovieHandler::with( DeleteMovieHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -264,7 +265,7 @@ mod tests {
#[test] #[test]
fn test_delete_movie_confirm_prompt_prompt_confirm() { fn test_delete_movie_confirm_prompt_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
let expected_delete_movie_params = DeleteMovieParams { let expected_delete_movie_params = DeleteMovieParams {
id: 1, id: 1,
delete_movie_files: true, delete_movie_files: true,
@@ -282,7 +283,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, DELETE_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, DELETE_MOVIE_SELECTION_BLOCKS.len() - 1);
DeleteMovieHandler::with( DeleteMovieHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -313,9 +314,25 @@ mod tests {
}); });
} }
#[rstest]
fn test_delete_movie_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = DeleteMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_delete_movie_params() { fn test_build_delete_movie_params() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.movies.set_items(vec![movie()]); app.data.radarr_data.movies.set_items(vec![movie()]);
app.data.radarr_data.delete_movie_files = true; app.data.radarr_data.delete_movie_files = true;
app.data.radarr_data.add_list_exclusion = true; app.data.radarr_data.add_list_exclusion = true;
@@ -325,7 +342,7 @@ mod tests {
add_list_exclusion: true, add_list_exclusion: true,
}; };
let delete_movie_params = DeleteMovieHandler::with( let delete_movie_params = DeleteMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -340,10 +357,10 @@ mod tests {
#[test] #[test]
fn test_delete_movie_handler_not_ready_when_loading() { fn test_delete_movie_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = DeleteMovieHandler::with( let handler = DeleteMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -355,10 +372,10 @@ mod tests {
#[test] #[test]
fn test_delete_movie_handler_ready_when_not_loading() { fn test_delete_movie_handler_ready_when_not_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = DeleteMovieHandler::with( let handler = DeleteMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteMoviePrompt, ActiveRadarrBlock::DeleteMoviePrompt,
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -7,7 +6,7 @@ use crate::models::servarr_data::radarr::modals::EditMovieModal;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, EDIT_MOVIE_BLOCKS};
use crate::models::Scrollable; use crate::models::Scrollable;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{handle_text_box_keys, handle_text_box_left_right_keys, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "edit_movie_handler_tests.rs"] #[path = "edit_movie_handler_tests.rs"]
@@ -20,54 +19,46 @@ pub(super) struct EditMovieHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> EditMovieHandler<'a, 'b> { impl EditMovieHandler<'_, '_> {
fn build_edit_movie_params(&mut self) -> EditMovieParams { fn build_edit_movie_params(&mut self) -> EditMovieParams {
let movie_id = self.app.data.radarr_data.movies.current_selection().id; let movie_id = self.app.data.radarr_data.movies.current_selection().id;
let tags = self let edit_movie_modal = self
.app .app
.data .data
.radarr_data .radarr_data
.edit_movie_modal .edit_movie_modal
.as_ref() .take()
.unwrap() .expect("Edit movie modal is None");
.tags let tags = edit_movie_modal.tags.text;
.text let EditMovieModal {
.clone(); monitored,
let params = { path,
let EditMovieModal { minimum_availability_list,
monitored, quality_profile_list,
path, ..
minimum_availability_list, } = edit_movie_modal;
quality_profile_list, let quality_profile = quality_profile_list.current_selection();
.. let quality_profile_id = *self
} = self.app.data.radarr_data.edit_movie_modal.as_ref().unwrap(); .app
let quality_profile = quality_profile_list.current_selection(); .data
let quality_profile_id = *self .radarr_data
.app .quality_profile_map
.data .iter()
.radarr_data .filter(|(_, value)| *value == quality_profile)
.quality_profile_map .map(|(key, _)| key)
.iter() .next()
.filter(|(_, value)| *value == quality_profile) .unwrap();
.map(|(key, _)| key)
.next()
.unwrap();
EditMovieParams { EditMovieParams {
movie_id, movie_id,
monitored: *monitored, monitored,
minimum_availability: Some(*minimum_availability_list.current_selection()), minimum_availability: Some(*minimum_availability_list.current_selection()),
quality_profile_id: Some(quality_profile_id), quality_profile_id: Some(quality_profile_id),
root_folder_path: Some(path.text.clone()), root_folder_path: Some(path.text),
tags: None, tags: None,
tag_input_string: Some(tags), tag_input_string: Some(tags),
clear_tags: false, clear_tags: false,
} }
};
self.app.data.radarr_data.edit_movie_modal = None;
params
} }
} }
@@ -76,7 +67,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
EDIT_MOVIE_BLOCKS.contains(&active_block) EDIT_MOVIE_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -384,7 +379,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for EditMovieHandler<'a,
ActiveRadarrBlock::EditMoviePrompt => { ActiveRadarrBlock::EditMoviePrompt => {
if self.app.data.radarr_data.selected_block.get_active_block() if self.app.data.radarr_data.selected_block.get_active_block()
== ActiveRadarrBlock::EditMovieConfirmPrompt == ActiveRadarrBlock::EditMovieConfirmPrompt
&& key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
@@ -2,6 +2,7 @@
mod tests { mod tests {
use bimap::BiMap; use bimap::BiMap;
use pretty_assertions::assert_str_eq; use pretty_assertions::assert_str_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -30,7 +31,7 @@ mod tests {
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app app
.data .data
@@ -43,7 +44,7 @@ mod tests {
if key == Key::Up { if key == Key::Up {
for i in (0..minimum_availability_vec.len()).rev() { for i in (0..minimum_availability_vec.len()).rev() {
EditMovieHandler::with( EditMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
@@ -65,7 +66,7 @@ mod tests {
} }
} else { } else {
for i in 0..minimum_availability_vec.len() { for i in 0..minimum_availability_vec.len() {
EditMovieHandler::with( EditMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
@@ -92,7 +93,7 @@ mod tests {
fn test_edit_movie_select_quality_profile_scroll( fn test_edit_movie_select_quality_profile_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app app
.data .data
@@ -103,7 +104,7 @@ mod tests {
.quality_profile_list .quality_profile_list
.set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]); .set_items(vec!["Test 1".to_owned(), "Test 2".to_owned()]);
EditMovieHandler::with( EditMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectQualityProfile, ActiveRadarrBlock::EditMovieSelectQualityProfile,
@@ -123,7 +124,7 @@ mod tests {
"Test 2" "Test 2"
); );
EditMovieHandler::with( EditMovieHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectQualityProfile, ActiveRadarrBlock::EditMovieSelectQualityProfile,
@@ -146,12 +147,12 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_movie_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditMovieHandler::with(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle(); EditMovieHandler::new(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle();
if key == Key::Up { if key == Key::Up {
assert_eq!( assert_eq!(
@@ -168,13 +169,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_movie_prompt_scroll_no_op_when_not_ready(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.down(); app.data.radarr_data.selected_block.down();
EditMovieHandler::with(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle(); EditMovieHandler::new(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle();
assert_eq!( assert_eq!(
app.data.radarr_data.selected_block.get_active_block(), app.data.radarr_data.selected_block.get_active_block(),
@@ -195,7 +196,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_select_minimum_availability_home_end() { fn test_edit_movie_select_minimum_availability_home_end() {
let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter()); let minimum_availability_vec = Vec::from_iter(MinimumAvailability::iter());
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app app
.data .data
@@ -206,7 +207,7 @@ mod tests {
.minimum_availability_list .minimum_availability_list
.set_items(minimum_availability_vec.clone()); .set_items(minimum_availability_vec.clone());
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
@@ -226,7 +227,7 @@ mod tests {
&minimum_availability_vec[minimum_availability_vec.len() - 1] &minimum_availability_vec[minimum_availability_vec.len() - 1]
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectMinimumAvailability, ActiveRadarrBlock::EditMovieSelectMinimumAvailability,
@@ -249,7 +250,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_select_quality_profile_scroll() { fn test_edit_movie_select_quality_profile_scroll() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app app
.data .data
@@ -264,7 +265,7 @@ mod tests {
"Test 3".to_owned(), "Test 3".to_owned(),
]); ]);
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectQualityProfile, ActiveRadarrBlock::EditMovieSelectQualityProfile,
@@ -284,7 +285,7 @@ mod tests {
"Test 3" "Test 3"
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieSelectQualityProfile, ActiveRadarrBlock::EditMovieSelectQualityProfile,
@@ -307,13 +308,13 @@ mod tests {
#[test] #[test]
fn test_edit_movie_path_input_home_end_keys() { fn test_edit_movie_path_input_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
path: "Test".into(), path: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -334,7 +335,7 @@ mod tests {
4 4
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -358,13 +359,13 @@ mod tests {
#[test] #[test]
fn test_edit_movie_tags_input_home_end_keys() { fn test_edit_movie_tags_input_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
tags: "Test".into(), tags: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -385,7 +386,7 @@ mod tests {
4 4
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -418,26 +419,26 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
EditMovieHandler::with(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle(); EditMovieHandler::new(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
EditMovieHandler::with(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle(); EditMovieHandler::new(key, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
#[test] #[test]
fn test_edit_movie_path_input_left_right_keys() { fn test_edit_movie_path_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
path: "Test".into(), path: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -458,7 +459,7 @@ mod tests {
1 1
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -482,13 +483,13 @@ mod tests {
#[test] #[test]
fn test_edit_movie_tags_input_left_right_keys() { fn test_edit_movie_tags_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
tags: "Test".into(), tags: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -509,7 +510,7 @@ mod tests {
1 1
); );
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -547,7 +548,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_path_input_submit() { fn test_edit_movie_path_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
path: "Test Path".into(), path: "Test Path".into(),
@@ -556,7 +557,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into());
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -582,7 +583,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_tags_input_submit() { fn test_edit_movie_tags_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
tags: "Test Tags".into(), tags: "Test Tags".into(),
@@ -591,7 +592,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePathInput.into());
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -617,7 +618,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_prompt_prompt_decline_submit() { fn test_edit_movie_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
@@ -628,7 +629,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1);
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -642,7 +643,7 @@ mod tests {
#[test] #[test]
fn test_edit_movie_confirm_prompt_prompt_confirmation_submit() { fn test_edit_movie_confirm_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_movie = EditMovieModal { let mut edit_movie = EditMovieModal {
tags: "usenet, testing".to_owned().into(), tags: "usenet, testing".to_owned().into(),
path: "/nfs/Test Path".to_owned().into(), path: "/nfs/Test Path".to_owned().into(),
@@ -681,7 +682,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1);
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -700,14 +701,14 @@ mod tests {
#[test] #[test]
fn test_edit_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_movie_confirm_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -729,12 +730,12 @@ mod tests {
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
Some(ActiveRadarrBlock::Movies), Some(ActiveRadarrBlock::Movies),
)); ));
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
app.push_navigation_stack(current_route); app.push_navigation_stack(current_route);
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -754,7 +755,7 @@ mod tests {
Some(true) Some(true)
); );
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -784,7 +785,7 @@ mod tests {
#[case] selected_block: ActiveRadarrBlock, #[case] selected_block: ActiveRadarrBlock,
#[case] y_index: usize, #[case] y_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack( app.push_navigation_stack(
( (
@@ -796,7 +797,7 @@ mod tests {
app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, y_index); app.data.radarr_data.selected_block.set_index(0, y_index);
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -821,7 +822,7 @@ mod tests {
fn test_edit_movie_prompt_selected_block_submit_no_op_when_not_ready( fn test_edit_movie_prompt_selected_block_submit_no_op_when_not_ready(
#[values(1, 2, 3, 4)] y_index: usize, #[values(1, 2, 3, 4)] y_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack( app.push_navigation_stack(
@@ -834,7 +835,7 @@ mod tests {
app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); app.data.radarr_data.selected_block = BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
app.data.radarr_data.selected_block.set_index(0, y_index); app.data.radarr_data.selected_block.set_index(0, y_index);
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -864,12 +865,12 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
EditMovieHandler::with( EditMovieHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -909,13 +910,13 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
EditMovieHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); EditMovieHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert!(!app.should_ignore_quit_key); assert!(!app.should_ignore_quit_key);
assert_eq!( assert_eq!(
@@ -926,12 +927,12 @@ mod tests {
#[test] #[test]
fn test_edit_movie_prompt_esc() { fn test_edit_movie_prompt_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::EditMoviePrompt.into());
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
EditMovieHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle(); EditMovieHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::EditMoviePrompt, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
@@ -948,12 +949,12 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool, #[values(true, false)] is_ready: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
EditMovieHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); EditMovieHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
} }
@@ -971,13 +972,13 @@ mod tests {
#[test] #[test]
fn test_edit_movie_path_input_backspace() { fn test_edit_movie_path_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
path: "Test".into(), path: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
@@ -1000,13 +1001,13 @@ mod tests {
#[test] #[test]
fn test_edit_movie_tags_input_backspace() { fn test_edit_movie_tags_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal { app.data.radarr_data.edit_movie_modal = Some(EditMovieModal {
tags: "Test".into(), tags: "Test".into(),
..EditMovieModal::default() ..EditMovieModal::default()
}); });
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
@@ -1029,11 +1030,11 @@ mod tests {
#[test] #[test]
fn test_edit_movie_path_input_char_key() { fn test_edit_movie_path_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
EditMovieHandler::with( EditMovieHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePathInput, ActiveRadarrBlock::EditMoviePathInput,
None, None,
@@ -1049,17 +1050,17 @@ mod tests {
.unwrap() .unwrap()
.path .path
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_movie_tags_input_char_key() { fn test_edit_movie_tags_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
EditMovieHandler::with( EditMovieHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::EditMovieTagsInput, ActiveRadarrBlock::EditMovieTagsInput,
None, None,
@@ -1075,13 +1076,13 @@ mod tests {
.unwrap() .unwrap()
.tags .tags
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_movie_confirm_prompt_prompt_confirm() { fn test_edit_movie_confirm_prompt_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_movie = EditMovieModal { let mut edit_movie = EditMovieModal {
tags: "usenet, testing".to_owned().into(), tags: "usenet, testing".to_owned().into(),
path: "/nfs/Test Path".to_owned().into(), path: "/nfs/Test Path".to_owned().into(),
@@ -1119,7 +1120,7 @@ mod tests {
.selected_block .selected_block
.set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_MOVIE_SELECTION_BLOCKS.len() - 1);
EditMovieHandler::with( EditMovieHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -1148,9 +1149,25 @@ mod tests {
}); });
} }
#[rstest]
fn test_edit_movie_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = EditMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_movie_params() { fn test_build_edit_movie_params() {
let mut app = App::default(); let mut app = App::test_default();
let mut edit_movie = EditMovieModal { let mut edit_movie = EditMovieModal {
tags: "usenet, testing".to_owned().into(), tags: "usenet, testing".to_owned().into(),
path: "/nfs/Test Path".to_owned().into(), path: "/nfs/Test Path".to_owned().into(),
@@ -1180,7 +1197,7 @@ mod tests {
..EditMovieParams::default() ..EditMovieParams::default()
}; };
let edit_movie_params = EditMovieHandler::with( let edit_movie_params = EditMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -1194,10 +1211,10 @@ mod tests {
#[test] #[test]
fn test_edit_movie_handler_is_not_ready_when_loading() { fn test_edit_movie_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = EditMovieHandler::with( let handler = EditMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -1209,10 +1226,10 @@ mod tests {
#[test] #[test]
fn test_edit_movie_handler_is_not_ready_when_edit_movie_modal_is_none() { fn test_edit_movie_handler_is_not_ready_when_edit_movie_modal_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = EditMovieHandler::with( let handler = EditMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -1224,11 +1241,11 @@ mod tests {
#[test] #[test]
fn test_edit_movie_handler_is_ready_when_edit_movie_modal_is_some() { fn test_edit_movie_handler_is_ready_when_edit_movie_modal_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default()); app.data.radarr_data.edit_movie_modal = Some(EditMovieModal::default());
let handler = EditMovieHandler::with( let handler = EditMovieHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -30,7 +30,7 @@ mod tests {
#[test] #[test]
fn test_movies_delete() { fn test_movies_delete() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -51,7 +51,7 @@ mod tests {
#[test] #[test]
fn test_movies_delete_no_op_when_not_ready() { fn test_movies_delete_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app app
@@ -60,7 +60,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle(); LibraryHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
} }
@@ -74,11 +74,11 @@ mod tests {
#[rstest] #[rstest]
fn test_movie_tab_left(#[values(true, false)] is_ready: bool) { fn test_movie_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(0); app.data.radarr_data.main_tabs.set_index(0);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -95,11 +95,11 @@ mod tests {
#[rstest] #[rstest]
fn test_movie_tab_right(#[values(true, false)] is_ready: bool) { fn test_movie_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(0); app.data.radarr_data.main_tabs.set_index(0);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -121,9 +121,9 @@ mod tests {
fn test_left_right_update_all_movies_prompt_toggle( fn test_left_right_update_all_movies_prompt_toggle(
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
LibraryHandler::with( LibraryHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -133,7 +133,7 @@ mod tests {
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
LibraryHandler::with( LibraryHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -156,14 +156,14 @@ mod tests {
#[test] #[test]
fn test_movie_details_submit() { fn test_movie_details_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle(); LibraryHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -173,7 +173,7 @@ mod tests {
#[test] #[test]
fn test_movie_details_submit_no_op_when_not_ready() { fn test_movie_details_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app app
@@ -182,14 +182,14 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle(); LibraryHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
} }
#[test] #[test]
fn test_update_all_movies_prompt_confirm_submit() { fn test_update_all_movies_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -199,7 +199,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
LibraryHandler::with( LibraryHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -217,7 +217,7 @@ mod tests {
#[test] #[test]
fn test_update_all_movies_prompt_decline_submit() { fn test_update_all_movies_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -226,7 +226,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
LibraryHandler::with( LibraryHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -253,12 +253,12 @@ mod tests {
#[test] #[test]
fn test_update_all_movies_prompt_blocks_esc() { fn test_update_all_movies_prompt_blocks_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
LibraryHandler::with( LibraryHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -272,7 +272,7 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
@@ -286,7 +286,7 @@ mod tests {
..StatefulTable::default() ..StatefulTable::default()
}; };
LibraryHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle(); LibraryHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::Movies, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -312,14 +312,14 @@ mod tests {
#[test] #[test]
fn test_movie_add_key() { fn test_movie_add_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.add.key, DEFAULT_KEYBINDINGS.add.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -337,7 +337,7 @@ mod tests {
#[test] #[test]
fn test_movie_add_key_no_op_when_not_ready() { fn test_movie_add_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app app
@@ -346,7 +346,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.add.key, DEFAULT_KEYBINDINGS.add.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -370,7 +370,7 @@ mod tests {
#[test] #[test]
fn test_movie_edit_key_no_op_when_not_ready() { fn test_movie_edit_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app app
@@ -379,7 +379,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.edit.key, DEFAULT_KEYBINDINGS.edit.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -393,14 +393,14 @@ mod tests {
#[test] #[test]
fn test_update_all_movies_key() { fn test_update_all_movies_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -416,7 +416,7 @@ mod tests {
#[test] #[test]
fn test_update_all_movies_key_no_op_when_not_ready() { fn test_update_all_movies_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app app
@@ -425,7 +425,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -438,7 +438,7 @@ mod tests {
#[test] #[test]
fn test_refresh_movies_key() { fn test_refresh_movies_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -446,7 +446,7 @@ mod tests {
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -460,7 +460,7 @@ mod tests {
#[test] #[test]
fn test_refresh_movies_key_no_op_when_not_ready() { fn test_refresh_movies_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app app
.data .data
@@ -469,7 +469,7 @@ mod tests {
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -483,7 +483,7 @@ mod tests {
#[test] #[test]
fn test_update_all_movies_prompt_confirm() { fn test_update_all_movies_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -492,7 +492,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
LibraryHandler::with( LibraryHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::UpdateAllMoviesPrompt, ActiveRadarrBlock::UpdateAllMoviesPrompt,
@@ -777,12 +777,28 @@ mod tests {
}); });
} }
#[rstest]
fn test_library_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = LibraryHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_library_handler_not_ready_when_loading() { fn test_library_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = LibraryHandler::with( let handler = LibraryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -794,10 +810,10 @@ mod tests {
#[test] #[test]
fn test_library_handler_not_ready_when_movies_is_empty() { fn test_library_handler_not_ready_when_movies_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = LibraryHandler::with( let handler = LibraryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
@@ -809,7 +825,7 @@ mod tests {
#[test] #[test]
fn test_library_handler_ready_when_not_loading_and_movies_is_not_empty() { fn test_library_handler_ready_when_not_loading_and_movies_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -817,7 +833,7 @@ mod tests {
.movies .movies
.set_items(vec![Movie::default()]); .set_items(vec![Movie::default()]);
let handler = LibraryHandler::with( let handler = LibraryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Movies, ActiveRadarrBlock::Movies,
+16 -14
View File
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
@@ -8,7 +7,6 @@ use crate::handlers::radarr_handlers::library::edit_movie_handler::EditMovieHand
use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler; use crate::handlers::radarr_handlers::library::movie_details_handler::MovieDetailsHandler;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
use crate::handle_table_events;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::models::radarr_models::Movie; use crate::models::radarr_models::Movie;
use crate::models::servarr_data::radarr::radarr_data::{ use crate::models::servarr_data::radarr::radarr_data::{
@@ -17,6 +15,7 @@ use crate::models::servarr_data::radarr::radarr_data::{
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::models::{BlockSelectionState, HorizontallyScrollableText}; use crate::models::{BlockSelectionState, HorizontallyScrollableText};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
mod add_movie_handler; mod add_movie_handler;
mod delete_movie_handler; mod delete_movie_handler;
@@ -34,7 +33,7 @@ pub(super) struct LibraryHandler<'a, 'b> {
context: Option<ActiveRadarrBlock>, context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> LibraryHandler<'a, 'b> { impl LibraryHandler<'_, '_> {
handle_table_events!(self, movies, self.app.data.radarr_data.movies, Movie); handle_table_events!(self, movies, self.app.data.radarr_data.movies, Movie);
} }
@@ -54,19 +53,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
if !self.handle_movies_table_events(movie_table_handling_config) { if !self.handle_movies_table_events(movie_table_handling_config) {
match self.active_radarr_block { match self.active_radarr_block {
_ if AddMovieHandler::accepts(self.active_radarr_block) => { _ if AddMovieHandler::accepts(self.active_radarr_block) => {
AddMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context) AddMovieHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle();
.handle();
} }
_ if DeleteMovieHandler::accepts(self.active_radarr_block) => { _ if DeleteMovieHandler::accepts(self.active_radarr_block) => {
DeleteMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context) DeleteMovieHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle(); .handle();
} }
_ if EditMovieHandler::accepts(self.active_radarr_block) => { _ if EditMovieHandler::accepts(self.active_radarr_block) => {
EditMovieHandler::with(self.key, self.app, self.active_radarr_block, self.context) EditMovieHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle(); .handle();
} }
_ if MovieDetailsHandler::accepts(self.active_radarr_block) => { _ if MovieDetailsHandler::accepts(self.active_radarr_block) => {
MovieDetailsHandler::with(self.key, self.app, self.active_radarr_block, self.context) MovieDetailsHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle(); .handle();
} }
_ => self.handle_key_event(), _ => self.handle_key_event(),
@@ -82,7 +80,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
|| LIBRARY_BLOCKS.contains(&active_block) || LIBRARY_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -162,7 +164,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::Movies => match self.key { ActiveRadarrBlock::Movies => match self.key {
_ if key == DEFAULT_KEYBINDINGS.edit.key => { _ if matches_key!(edit, key) => {
self.app.push_navigation_stack( self.app.push_navigation_stack(
( (
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -174,25 +176,25 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for LibraryHandler<'a, '
self.app.data.radarr_data.selected_block = self.app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
} }
_ if key == DEFAULT_KEYBINDINGS.add.key => { _ if matches_key!(add, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into()); .push_navigation_stack(ActiveRadarrBlock::AddMovieSearchInput.into());
self.app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default()); self.app.data.radarr_data.add_movie_search = Some(HorizontallyScrollableText::default());
self.app.should_ignore_quit_key = true; self.app.should_ignore_quit_key = true;
} }
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::UpdateAllMoviesPrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::UpdateAllMoviesPrompt => { ActiveRadarrBlock::UpdateAllMoviesPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAllMovies); self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::UpdateAllMovies);
@@ -1,9 +1,7 @@
use serde_json::Number; use serde_json::Number;
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::models::radarr_models::{ use crate::models::radarr_models::{
@@ -16,6 +14,7 @@ use crate::models::servarr_models::Language;
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::models::{BlockSelectionState, Scrollable}; use crate::models::{BlockSelectionState, Scrollable};
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "movie_details_handler_tests.rs"] #[path = "movie_details_handler_tests.rs"]
@@ -28,7 +27,7 @@ pub(super) struct MovieDetailsHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> MovieDetailsHandler<'a, 'b> { impl MovieDetailsHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
movie_releases, movie_releases,
@@ -136,7 +135,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
MOVIE_DETAILS_BLOCKS.contains(&active_block) MOVIE_DETAILS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -245,13 +248,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
| ActiveRadarrBlock::Cast | ActiveRadarrBlock::Cast
| ActiveRadarrBlock::Crew | ActiveRadarrBlock::Crew
| ActiveRadarrBlock::ManualSearch => match self.key { | ActiveRadarrBlock::ManualSearch => match self.key {
_ if self.key == DEFAULT_KEYBINDINGS.left.key => { _ if matches_key!(left, self.key) => {
self.app.data.radarr_data.movie_info_tabs.previous(); self.app.data.radarr_data.movie_info_tabs.previous();
self.app.pop_and_push_navigation_stack( self.app.pop_and_push_navigation_stack(
self.app.data.radarr_data.movie_info_tabs.get_active_route(), self.app.data.radarr_data.movie_info_tabs.get_active_route(),
); );
} }
_ if self.key == DEFAULT_KEYBINDINGS.right.key => { _ if matches_key!(right, self.key) => {
self.app.data.radarr_data.movie_info_tabs.next(); self.app.data.radarr_data.movie_info_tabs.next();
self.app.pop_and_push_navigation_stack( self.app.pop_and_push_navigation_stack(
self.app.data.radarr_data.movie_info_tabs.get_active_route(), self.app.data.radarr_data.movie_info_tabs.get_active_route(),
@@ -332,12 +335,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
| ActiveRadarrBlock::Cast | ActiveRadarrBlock::Cast
| ActiveRadarrBlock::Crew | ActiveRadarrBlock::Crew
| ActiveRadarrBlock::ManualSearch => match self.key { | ActiveRadarrBlock::ManualSearch => match self.key {
_ if key == DEFAULT_KEYBINDINGS.auto_search.key => { _ if matches_key!(auto_search, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::AutomaticallySearchMoviePrompt.into()); .push_navigation_stack(ActiveRadarrBlock::AutomaticallySearchMoviePrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.edit.key => { _ if matches_key!(edit, key) => {
self.app.push_navigation_stack( self.app.push_navigation_stack(
( (
ActiveRadarrBlock::EditMoviePrompt, ActiveRadarrBlock::EditMoviePrompt,
@@ -349,35 +352,33 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for MovieDetailsHandler<
self.app.data.radarr_data.selected_block = self.app.data.radarr_data.selected_block =
BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_MOVIE_SELECTION_BLOCKS);
} }
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::UpdateAndScanPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::UpdateAndScanPrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self self
.app .app
.pop_and_push_navigation_stack(self.active_radarr_block.into()); .pop_and_push_navigation_stack(self.active_radarr_block.into());
} }
_ => (), _ => (),
}, },
ActiveRadarrBlock::AutomaticallySearchMoviePrompt ActiveRadarrBlock::AutomaticallySearchMoviePrompt if matches_key!(confirm, key) => {
if key == DEFAULT_KEYBINDINGS.confirm.key =>
{
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::TriggerAutomaticSearch(self.extract_movie_id())); Some(RadarrEvent::TriggerAutomaticSearch(self.extract_movie_id()));
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
} }
ActiveRadarrBlock::UpdateAndScanPrompt if key == DEFAULT_KEYBINDINGS.confirm.key => { ActiveRadarrBlock::UpdateAndScanPrompt if matches_key!(confirm, key) => {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::UpdateAndScan(self.extract_movie_id())); Some(RadarrEvent::UpdateAndScan(self.extract_movie_id()));
self.app.pop_navigation_stack(); self.app.pop_navigation_stack();
} }
ActiveRadarrBlock::ManualSearchConfirmPrompt if key == DEFAULT_KEYBINDINGS.confirm.key => { ActiveRadarrBlock::ManualSearchConfirmPrompt if matches_key!(confirm, key) => {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DownloadRelease( self.app.data.radarr_data.prompt_confirm_action = Some(RadarrEvent::DownloadRelease(
self.build_radarr_release_download_body(), self.build_radarr_release_download_body(),
@@ -31,13 +31,13 @@ mod tests {
#[test] #[test]
fn test_movie_details_scroll() { fn test_movie_details_scroll() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()), movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.up.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -57,7 +57,7 @@ mod tests {
0 0
); );
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.down.key, DEFAULT_KEYBINDINGS.down.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -80,14 +80,14 @@ mod tests {
#[test] #[test]
fn test_movie_details_scroll_no_op_if_not_ready() { fn test_movie_details_scroll_no_op_if_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()), movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.up.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -107,7 +107,7 @@ mod tests {
0 0
); );
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.down.key, DEFAULT_KEYBINDINGS.down.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -137,14 +137,14 @@ mod tests {
#[test] #[test]
fn test_movie_details_home_end() { fn test_movie_details_home_end() {
let mut app = App::default(); let mut app = App::test_default();
let movie_details_modal = MovieDetailsModal { let movie_details_modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()), movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}; };
app.data.radarr_data.movie_details_modal = Some(movie_details_modal); app.data.radarr_data.movie_details_modal = Some(movie_details_modal);
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -164,7 +164,7 @@ mod tests {
1 1
); );
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -187,7 +187,7 @@ mod tests {
#[test] #[test]
fn test_movie_details_home_end_no_op_when_not_ready() { fn test_movie_details_home_end_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let movie_details_modal = MovieDetailsModal { let movie_details_modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()), movie_details: ScrollableText::with_string("Test 1\nTest 2".to_owned()),
@@ -195,7 +195,7 @@ mod tests {
}; };
app.data.radarr_data.movie_details_modal = Some(movie_details_modal); app.data.radarr_data.movie_details_modal = Some(movie_details_modal);
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -215,7 +215,7 @@ mod tests {
0 0
); );
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -253,13 +253,13 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(Key::Left, Key::Right)] key: Key, #[values(Key::Left, Key::Right)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
MovieDetailsHandler::with(key, &mut app, active_radarr_block, None).handle(); MovieDetailsHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
MovieDetailsHandler::with(key, &mut app, active_radarr_block, None).handle(); MovieDetailsHandler::new(key, &mut app, active_radarr_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
} }
@@ -276,7 +276,7 @@ mod tests {
#[case] right_block: ActiveRadarrBlock, #[case] right_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool, #[values(true, false)] is_ready: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(right_block.into()); app.push_navigation_stack(right_block.into());
app.data.radarr_data.movie_info_tabs.index = app app.data.radarr_data.movie_info_tabs.index = app
@@ -288,7 +288,7 @@ mod tests {
.position(|tab_route| tab_route.route == right_block.into()) .position(|tab_route| tab_route.route == right_block.into())
.unwrap_or_default(); .unwrap_or_default();
MovieDetailsHandler::with(DEFAULT_KEYBINDINGS.left.key, &mut app, right_block, None).handle(); MovieDetailsHandler::new(DEFAULT_KEYBINDINGS.left.key, &mut app, right_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -296,7 +296,7 @@ mod tests {
); );
assert_eq!(app.get_current_route(), left_block.into()); assert_eq!(app.get_current_route(), left_block.into());
MovieDetailsHandler::with(DEFAULT_KEYBINDINGS.right.key, &mut app, left_block, None).handle(); MovieDetailsHandler::new(DEFAULT_KEYBINDINGS.right.key, &mut app, left_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -319,7 +319,7 @@ mod tests {
#[test] #[test]
fn test_manual_search_submit() { fn test_manual_search_submit() {
let mut app = App::default(); let mut app = App::test_default();
let mut modal = MovieDetailsModal { let mut modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()), movie_details: ScrollableText::with_string("test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -330,7 +330,7 @@ mod tests {
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into());
MovieDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::ManualSearch, None) MovieDetailsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::ManualSearch, None)
.handle(); .handle();
assert_eq!( assert_eq!(
@@ -341,7 +341,7 @@ mod tests {
#[test] #[test]
fn test_manual_search_submit_no_op_when_not_ready() { fn test_manual_search_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()), movie_details: ScrollableText::with_string("test".to_owned()),
@@ -349,7 +349,7 @@ mod tests {
}); });
app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into()); app.push_navigation_stack(ActiveRadarrBlock::ManualSearch.into());
MovieDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::ManualSearch, None) MovieDetailsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::ManualSearch, None)
.handle(); .handle();
assert_eq!( assert_eq!(
@@ -376,7 +376,7 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
let mut movie_details_modal = MovieDetailsModal { let mut movie_details_modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()), movie_details: ScrollableText::with_string("test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -390,7 +390,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
MovieDetailsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); MovieDetailsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -412,7 +412,7 @@ mod tests {
)] )]
prompt_block: ActiveRadarrBlock, prompt_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()), movie_details: ScrollableText::with_string("test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -420,7 +420,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
MovieDetailsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); MovieDetailsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -455,13 +455,13 @@ mod tests {
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool, #[values(true, false)] is_ready: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
MovieDetailsHandler::with(ESC_KEY, &mut app, active_radarr_block, None).handle(); MovieDetailsHandler::new(ESC_KEY, &mut app, active_radarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
assert_movie_info_tabs_reset!(app.data.radarr_data); assert_movie_info_tabs_reset!(app.data.radarr_data);
@@ -477,14 +477,14 @@ mod tests {
prompt_block: ActiveRadarrBlock, prompt_block: ActiveRadarrBlock,
#[values(true, false)] is_ready: bool, #[values(true, false)] is_ready: bool,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data = create_test_radarr_data(); app.data.radarr_data = create_test_radarr_data();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
app.push_navigation_stack(ActiveRadarrBlock::Movies.into()); app.push_navigation_stack(ActiveRadarrBlock::Movies.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
MovieDetailsHandler::with(ESC_KEY, &mut app, prompt_block, None).handle(); MovieDetailsHandler::new(ESC_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.radarr_data.prompt_confirm); assert!(!app.data.radarr_data.prompt_confirm);
assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::Movies.into());
@@ -521,7 +521,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
let mut modal = MovieDetailsModal { let mut modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test".to_owned()), movie_details: ScrollableText::with_string("Test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -536,7 +536,7 @@ mod tests {
.set_items(vec![RadarrRelease::default()]); .set_items(vec![RadarrRelease::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.auto_search.key, DEFAULT_KEYBINDINGS.auto_search.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -562,7 +562,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
@@ -570,7 +570,7 @@ mod tests {
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.auto_search.key, DEFAULT_KEYBINDINGS.auto_search.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -612,7 +612,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
@@ -620,7 +620,7 @@ mod tests {
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.edit.key, DEFAULT_KEYBINDINGS.edit.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -644,7 +644,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
let mut modal = MovieDetailsModal { let mut modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test".to_owned()), movie_details: ScrollableText::with_string("Test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -659,7 +659,7 @@ mod tests {
.set_items(vec![RadarrRelease::default()]); .set_items(vec![RadarrRelease::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -685,7 +685,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
@@ -693,7 +693,7 @@ mod tests {
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -716,7 +716,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
let mut modal = MovieDetailsModal { let mut modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test".to_owned()), movie_details: ScrollableText::with_string("Test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -731,7 +731,7 @@ mod tests {
.set_items(vec![RadarrRelease::default()]); .set_items(vec![RadarrRelease::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -755,7 +755,7 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
app.is_routing = false; app.is_routing = false;
@@ -764,7 +764,7 @@ mod tests {
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -794,7 +794,7 @@ mod tests {
#[case] prompt_block: ActiveRadarrBlock, #[case] prompt_block: ActiveRadarrBlock,
#[case] expected_action: RadarrEvent, #[case] expected_action: RadarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
let mut movie_details_modal = MovieDetailsModal { let mut movie_details_modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("test".to_owned()), movie_details: ScrollableText::with_string("test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
@@ -808,7 +808,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into()); app.push_navigation_stack(ActiveRadarrBlock::MovieDetails.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
MovieDetailsHandler::with( MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
prompt_block, prompt_block,
@@ -830,7 +830,7 @@ mod tests {
#[test] #[test]
fn test_build_radarr_release_download_body() { fn test_build_radarr_release_download_body() {
let mut app = App::default(); let mut app = App::test_default();
let mut movie_details_modal = MovieDetailsModal::default(); let mut movie_details_modal = MovieDetailsModal::default();
movie_details_modal movie_details_modal
.movie_releases .movie_releases
@@ -843,7 +843,7 @@ mod tests {
movie_id: 1, movie_id: 1,
}; };
let body = MovieDetailsHandler::with( let body = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::ManualSearchConfirmPrompt, ActiveRadarrBlock::ManualSearchConfirmPrompt,
@@ -856,10 +856,10 @@ mod tests {
#[test] #[test]
fn test_extract_movie_id() { fn test_extract_movie_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.movies.set_items(vec![movie()]); app.data.radarr_data.movies.set_items(vec![movie()]);
let movie_id = MovieDetailsHandler::with( let movie_id = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::AutomaticallySearchMoviePrompt, ActiveRadarrBlock::AutomaticallySearchMoviePrompt,
@@ -1042,6 +1042,22 @@ mod tests {
}); });
} }
#[rstest]
fn test_movie_details_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[rstest] #[rstest]
fn test_movie_details_handler_is_not_ready_when_loading( fn test_movie_details_handler_is_not_ready_when_loading(
#[values( #[values(
@@ -1055,7 +1071,7 @@ mod tests {
)] )]
movie_details_block: ActiveRadarrBlock, movie_details_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let mut modal = MovieDetailsModal { let mut modal = MovieDetailsModal {
movie_details: ScrollableText::with_string("Test".to_owned()), movie_details: ScrollableText::with_string("Test".to_owned()),
@@ -1071,7 +1087,7 @@ mod tests {
.set_items(vec![RadarrRelease::default()]); .set_items(vec![RadarrRelease::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
movie_details_block, movie_details_block,
@@ -1083,11 +1099,11 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_not_ready_when_no_movie_details_are_in_modal() { fn test_movie_details_handler_is_not_ready_when_no_movie_details_are_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default()); app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal::default());
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -1099,14 +1115,14 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_ready_when_movie_details_are_in_modal() { fn test_movie_details_handler_is_ready_when_movie_details_are_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal { app.data.radarr_data.movie_details_modal = Some(MovieDetailsModal {
movie_details: ScrollableText::with_string("Test".to_owned()), movie_details: ScrollableText::with_string("Test".to_owned()),
..MovieDetailsModal::default() ..MovieDetailsModal::default()
}); });
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieDetails, ActiveRadarrBlock::MovieDetails,
@@ -1118,7 +1134,7 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_ready_when_movie_history_is_in_modal() { fn test_movie_details_handler_is_ready_when_movie_history_is_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let mut modal = MovieDetailsModal::default(); let mut modal = MovieDetailsModal::default();
modal modal
@@ -1126,7 +1142,7 @@ mod tests {
.set_items(vec![MovieHistoryItem::default()]); .set_items(vec![MovieHistoryItem::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::MovieHistory, ActiveRadarrBlock::MovieHistory,
@@ -1138,13 +1154,13 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_ready_when_movie_cast_is_in_modal() { fn test_movie_details_handler_is_ready_when_movie_cast_is_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let mut modal = MovieDetailsModal::default(); let mut modal = MovieDetailsModal::default();
modal.movie_cast.set_items(vec![Credit::default()]); modal.movie_cast.set_items(vec![Credit::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Cast, ActiveRadarrBlock::Cast,
@@ -1156,13 +1172,13 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_ready_when_movie_crew_is_in_modal() { fn test_movie_details_handler_is_ready_when_movie_crew_is_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let mut modal = MovieDetailsModal::default(); let mut modal = MovieDetailsModal::default();
modal.movie_crew.set_items(vec![Credit::default()]); modal.movie_crew.set_items(vec![Credit::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::Crew, ActiveRadarrBlock::Crew,
@@ -1174,7 +1190,7 @@ mod tests {
#[test] #[test]
fn test_movie_details_handler_is_ready_when_movie_releases_is_in_modal() { fn test_movie_details_handler_is_ready_when_movie_releases_is_in_modal() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let mut modal = MovieDetailsModal::default(); let mut modal = MovieDetailsModal::default();
modal modal
@@ -1182,7 +1198,7 @@ mod tests {
.set_items(vec![RadarrRelease::default()]); .set_items(vec![RadarrRelease::default()]);
app.data.radarr_data.movie_details_modal = Some(modal); app.data.radarr_data.movie_details_modal = Some(modal);
let handler = MovieDetailsHandler::with( let handler = MovieDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::ManualSearch, ActiveRadarrBlock::ManualSearch,
+19 -22
View File
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::handlers::radarr_handlers::blocklist::BlocklistHandler; use crate::handlers::radarr_handlers::blocklist::BlocklistHandler;
use crate::handlers::radarr_handlers::collections::CollectionsHandler; use crate::handlers::radarr_handlers::collections::CollectionsHandler;
use crate::handlers::radarr_handlers::downloads::DownloadsHandler; use crate::handlers::radarr_handlers::downloads::DownloadsHandler;
@@ -8,7 +7,7 @@ use crate::handlers::radarr_handlers::root_folders::RootFoldersHandler;
use crate::handlers::radarr_handlers::system::SystemHandler; use crate::handlers::radarr_handlers::system::SystemHandler;
use crate::handlers::KeyEventHandler; use crate::handlers::KeyEventHandler;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::{App, Key}; use crate::{matches_key, App, Key};
mod blocklist; mod blocklist;
mod collections; mod collections;
@@ -37,27 +36,25 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
fn handle(&mut self) { fn handle(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
_ if LibraryHandler::accepts(self.active_radarr_block) => { _ if LibraryHandler::accepts(self.active_radarr_block) => {
LibraryHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle(); LibraryHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle();
} }
_ if CollectionsHandler::accepts(self.active_radarr_block) => { _ if CollectionsHandler::accepts(self.active_radarr_block) => {
CollectionsHandler::with(self.key, self.app, self.active_radarr_block, self.context) CollectionsHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
.handle()
} }
_ if IndexersHandler::accepts(self.active_radarr_block) => { _ if IndexersHandler::accepts(self.active_radarr_block) => {
IndexersHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() IndexersHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
} }
_ if SystemHandler::accepts(self.active_radarr_block) => { _ if SystemHandler::accepts(self.active_radarr_block) => {
SystemHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() SystemHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
} }
_ if DownloadsHandler::accepts(self.active_radarr_block) => { _ if DownloadsHandler::accepts(self.active_radarr_block) => {
DownloadsHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() DownloadsHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
} }
_ if RootFoldersHandler::accepts(self.active_radarr_block) => { _ if RootFoldersHandler::accepts(self.active_radarr_block) => {
RootFoldersHandler::with(self.key, self.app, self.active_radarr_block, self.context) RootFoldersHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
.handle()
} }
_ if BlocklistHandler::accepts(self.active_radarr_block) => { _ if BlocklistHandler::accepts(self.active_radarr_block) => {
BlocklistHandler::with(self.key, self.app, self.active_radarr_block, self.context).handle() BlocklistHandler::new(self.key, self.app, self.active_radarr_block, self.context).handle()
} }
_ => self.handle_key_event(), _ => self.handle_key_event(),
} }
@@ -67,7 +64,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
true true
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -111,11 +112,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RadarrHandler<'a, 'b
pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: Key) { pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: Key) {
let key_ref = key; let key_ref = key;
match key_ref { match key_ref {
_ if key == DEFAULT_KEYBINDINGS.left.key => { _ if matches_key!(left, key, app.should_ignore_quit_key) => {
app.data.radarr_data.main_tabs.previous(); app.data.radarr_data.main_tabs.previous();
app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route()); app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route());
} }
_ if key == DEFAULT_KEYBINDINGS.right.key => { _ if matches_key!(right, key, app.should_ignore_quit_key) => {
app.data.radarr_data.main_tabs.next(); app.data.radarr_data.main_tabs.next();
app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route()); app.pop_and_push_navigation_stack(app.data.radarr_data.main_tabs.get_active_route());
} }
@@ -126,10 +127,8 @@ pub fn handle_change_tab_left_right_keys(app: &mut App<'_>, key: Key) {
#[macro_export] #[macro_export]
macro_rules! search_table { macro_rules! search_table {
($app:expr, $data_ref:ident, $error_block:expr) => { ($app:expr, $data_ref:ident, $error_block:expr) => {
let search_index = if let Some(search_str) = $app.data.radarr_data.search.as_ref() { let search_index = if let Some(search_str) = $app.data.radarr_data.search.take() {
let search_string = search_str.text.clone().to_lowercase(); let search_string = search_str.text.to_lowercase();
$app.data.radarr_data.search = None;
$app $app
.data .data
@@ -153,10 +152,8 @@ macro_rules! search_table {
} }
}; };
($app:expr, $data_ref:ident, $error_block:expr, $option:ident) => { ($app:expr, $data_ref:ident, $error_block:expr, $option:ident) => {
let search_index = if let Some(search_str) = $app.data.radarr_data.search.as_ref() { let search_index = if let Some(search_str) = $app.data.radarr_data.search.take() {
let search_string = search_str.text.clone().to_lowercase(); let search_string = search_str.text.to_lowercase();
$app.data.radarr_data.search = None;
$app $app
.data .data
@@ -16,7 +16,7 @@ pub(in crate::handlers::radarr_handlers) mod utils {
#[macro_export] #[macro_export]
macro_rules! test_edit_movie_key { macro_rules! test_edit_movie_key {
($handler:ident, $block:expr, $context:expr) => { ($handler:ident, $block:expr, $context:expr) => {
let mut app = App::default(); let mut app = App::test_default();
let mut radarr_data = RadarrData { let mut radarr_data = RadarrData {
quality_profile_map: BiMap::from_iter([ quality_profile_map: BiMap::from_iter([
(2222, "HD - 1080p".to_owned()), (2222, "HD - 1080p".to_owned()),
@@ -35,7 +35,7 @@ pub(in crate::handlers::radarr_handlers) mod utils {
}]); }]);
app.data.radarr_data = radarr_data; app.data.radarr_data = radarr_data;
$handler::with(DEFAULT_KEYBINDINGS.edit.key, &mut app, $block, None).handle(); $handler::new(DEFAULT_KEYBINDINGS.edit.key, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -131,7 +131,7 @@ pub(in crate::handlers::radarr_handlers) mod utils {
#[macro_export] #[macro_export]
macro_rules! test_edit_collection_key { macro_rules! test_edit_collection_key {
($handler:ident, $block:expr, $context:expr) => { ($handler:ident, $block:expr, $context:expr) => {
let mut app = App::default(); let mut app = App::test_default();
let mut radarr_data = RadarrData { let mut radarr_data = RadarrData {
quality_profile_map: BiMap::from_iter([ quality_profile_map: BiMap::from_iter([
(2222, "HD - 1080p".to_owned()), (2222, "HD - 1080p".to_owned()),
@@ -149,7 +149,7 @@ pub(in crate::handlers::radarr_handlers) mod utils {
}]); }]);
app.data.radarr_data = radarr_data; app.data.radarr_data = radarr_data;
$handler::with(DEFAULT_KEYBINDINGS.edit.key, &mut app, $block, None).handle(); $handler::new(DEFAULT_KEYBINDINGS.edit.key, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -24,7 +24,7 @@ mod tests {
#[case] left_block: ActiveRadarrBlock, #[case] left_block: ActiveRadarrBlock,
#[case] right_block: ActiveRadarrBlock, #[case] right_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.main_tabs.set_index(index); app.data.radarr_data.main_tabs.set_index(index);
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.key); handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.key);
@@ -46,6 +46,76 @@ mod tests {
assert_eq!(app.get_current_route(), right_block.into()); assert_eq!(app.get_current_route(), right_block.into());
} }
#[rstest]
#[case(0, ActiveRadarrBlock::System, ActiveRadarrBlock::Collections)]
#[case(1, ActiveRadarrBlock::Movies, ActiveRadarrBlock::Downloads)]
#[case(2, ActiveRadarrBlock::Collections, ActiveRadarrBlock::Blocklist)]
#[case(3, ActiveRadarrBlock::Downloads, ActiveRadarrBlock::RootFolders)]
#[case(4, ActiveRadarrBlock::Blocklist, ActiveRadarrBlock::Indexers)]
#[case(5, ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::System)]
#[case(6, ActiveRadarrBlock::Indexers, ActiveRadarrBlock::Movies)]
fn test_radarr_handler_change_tab_left_right_keys_alt_navigation(
#[case] index: usize,
#[case] left_block: ActiveRadarrBlock,
#[case] right_block: ActiveRadarrBlock,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = false;
app.data.radarr_data.main_tabs.set_index(index);
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.alt.unwrap());
assert_eq!(
app.data.radarr_data.main_tabs.get_active_route(),
left_block.into()
);
assert_eq!(app.get_current_route(), left_block.into());
app.data.radarr_data.main_tabs.set_index(index);
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.right.alt.unwrap());
assert_eq!(
app.data.radarr_data.main_tabs.get_active_route(),
right_block.into()
);
assert_eq!(app.get_current_route(), right_block.into());
}
#[rstest]
#[case(0, ActiveRadarrBlock::Movies)]
#[case(1, ActiveRadarrBlock::Collections)]
#[case(2, ActiveRadarrBlock::Downloads)]
#[case(3, ActiveRadarrBlock::Blocklist)]
#[case(4, ActiveRadarrBlock::RootFolders)]
#[case(5, ActiveRadarrBlock::Indexers)]
#[case(6, ActiveRadarrBlock::System)]
fn test_radarr_handler_change_tab_left_right_keys_alt_navigation_no_op_when_ignoring_quit_key(
#[case] index: usize,
#[case] block: ActiveRadarrBlock,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = true;
app.push_navigation_stack(block.into());
app.data.radarr_data.main_tabs.set_index(index);
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.left.alt.unwrap());
assert_eq!(
app.data.radarr_data.main_tabs.get_active_route(),
block.into()
);
assert_eq!(app.get_current_route(), block.into());
handle_change_tab_left_right_keys(&mut app, DEFAULT_KEYBINDINGS.right.alt.unwrap());
assert_eq!(
app.data.radarr_data.main_tabs.get_active_route(),
block.into()
);
assert_eq!(app.get_current_route(), block.into());
}
#[rstest] #[rstest]
fn test_delegates_system_blocks_to_system_handler( fn test_delegates_system_blocks_to_system_handler(
#[values( #[values(
@@ -217,12 +287,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_radarr_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = RadarrHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::Movies,
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_radarr_handler_is_ready() { fn test_radarr_handler_is_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = RadarrHandler::with( let handler = RadarrHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
@@ -8,7 +7,9 @@ use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, ROOT_F
use crate::models::servarr_models::{AddRootFolderBody, RootFolder}; use crate::models::servarr_models::{AddRootFolderBody, RootFolder};
use crate::models::HorizontallyScrollableText; use crate::models::HorizontallyScrollableText;
use crate::network::radarr_network::RadarrEvent; use crate::network::radarr_network::RadarrEvent;
use crate::{handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{
handle_table_events, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
};
#[cfg(test)] #[cfg(test)]
#[path = "root_folders_handler_tests.rs"] #[path = "root_folders_handler_tests.rs"]
@@ -21,7 +22,7 @@ pub(super) struct RootFoldersHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> RootFoldersHandler<'a, 'b> { impl RootFoldersHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
root_folders, root_folders,
@@ -30,19 +31,17 @@ impl<'a, 'b> RootFoldersHandler<'a, 'b> {
); );
fn build_add_root_folder_body(&mut self) -> AddRootFolderBody { fn build_add_root_folder_body(&mut self) -> AddRootFolderBody {
let path = self let edit_root_folder = self
.app .app
.data .data
.radarr_data .radarr_data
.edit_root_folder .edit_root_folder
.as_ref() .take()
.unwrap() .expect("AddRootFolder is None");
.text
.clone();
self.app.data.radarr_data.edit_root_folder = None; AddRootFolderBody {
path: edit_root_folder.text,
AddRootFolderBody { path } }
} }
fn extract_root_folder_id(&mut self) -> i64 { fn extract_root_folder_id(&mut self) -> i64 {
@@ -70,7 +69,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
ROOT_FOLDERS_BLOCKS.contains(&active_block) ROOT_FOLDERS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -197,10 +200,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
let key = self.key; let key = self.key;
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::RootFolders => match self.key { ActiveRadarrBlock::RootFolders => match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ if key == DEFAULT_KEYBINDINGS.add.key => { _ if matches_key!(add, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into()); .push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into());
@@ -217,7 +220,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for RootFoldersHandler<'
) )
} }
ActiveRadarrBlock::DeleteRootFolderPrompt => { ActiveRadarrBlock::DeleteRootFolderPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
Some(RadarrEvent::DeleteRootFolder(self.extract_root_folder_id())); Some(RadarrEvent::DeleteRootFolder(self.extract_root_folder_id()));
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -22,7 +23,7 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_home_end_keys() { fn test_add_root_folder_prompt_home_end_keys() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -30,7 +31,7 @@ mod tests {
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some("Test".into()); app.data.radarr_data.edit_root_folder = Some("Test".into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -50,7 +51,7 @@ mod tests {
4 4
); );
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -81,14 +82,14 @@ mod tests {
#[test] #[test]
fn test_delete_root_folder_prompt() { fn test_delete_root_folder_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.root_folders .root_folders
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle(); RootFoldersHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -98,7 +99,7 @@ mod tests {
#[test] #[test]
fn test_delete_root_folder_prompt_no_op_when_not_ready() { fn test_delete_root_folder_prompt_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app app
@@ -107,7 +108,7 @@ mod tests {
.root_folders .root_folders
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
RootFoldersHandler::with(DELETE_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle(); RootFoldersHandler::new(DELETE_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -126,11 +127,11 @@ mod tests {
#[rstest] #[rstest]
fn test_root_folders_tab_left(#[values(true, false)] is_ready: bool) { fn test_root_folders_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(4); app.data.radarr_data.main_tabs.set_index(4);
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -147,11 +148,11 @@ mod tests {
#[rstest] #[rstest]
fn test_root_folders_tab_right(#[values(true, false)] is_ready: bool) { fn test_root_folders_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(4); app.data.radarr_data.main_tabs.set_index(4);
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -170,9 +171,9 @@ mod tests {
fn test_left_right_delete_root_folder_prompt_toggle( fn test_left_right_delete_root_folder_prompt_toggle(
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
RootFoldersHandler::with( RootFoldersHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -182,7 +183,7 @@ mod tests {
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
RootFoldersHandler::with( RootFoldersHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -195,10 +196,10 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_left_right_keys() { fn test_add_root_folder_prompt_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_root_folder = Some("Test".into()); app.data.radarr_data.edit_root_folder = Some("Test".into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -218,7 +219,7 @@ mod tests {
1 1
); );
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -251,7 +252,7 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_confirm_submit() { fn test_add_root_folder_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
let expected_add_root_folder_body = AddRootFolderBody { let expected_add_root_folder_body = AddRootFolderBody {
path: "Test".to_owned(), path: "Test".to_owned(),
}; };
@@ -266,7 +267,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into());
RootFoldersHandler::with( RootFoldersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -288,14 +289,14 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_confirm_submit_noop_on_empty_folder() { fn test_add_root_folder_prompt_confirm_submit_noop_on_empty_folder() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default()); app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default());
app.data.radarr_data.prompt_confirm = false; app.data.radarr_data.prompt_confirm = false;
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into());
RootFoldersHandler::with( RootFoldersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -314,7 +315,7 @@ mod tests {
#[test] #[test]
fn test_delete_root_folder_prompt_confirm_submit() { fn test_delete_root_folder_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -324,7 +325,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
RootFoldersHandler::with( RootFoldersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -345,7 +346,7 @@ mod tests {
#[test] #[test]
fn test_delete_root_folder_prompt_decline_submit() { fn test_delete_root_folder_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -354,7 +355,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
RootFoldersHandler::with( RootFoldersHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -380,12 +381,12 @@ mod tests {
#[test] #[test]
fn test_delete_root_folder_prompt_block_esc() { fn test_delete_root_folder_prompt_block_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
RootFoldersHandler::with( RootFoldersHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -402,13 +403,13 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_esc() { fn test_add_root_folder_prompt_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::AddRootFolderPrompt.into());
app.data.radarr_data.edit_root_folder = Some("/nfs/test".into()); app.data.radarr_data.edit_root_folder = Some("/nfs/test".into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
RootFoldersHandler::with( RootFoldersHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -428,13 +429,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
RootFoldersHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle(); RootFoldersHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::RootFolders, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -453,14 +454,14 @@ mod tests {
#[test] #[test]
fn test_root_folder_add() { fn test_root_folder_add() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.root_folders .root_folders
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.add.key, DEFAULT_KEYBINDINGS.add.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -478,7 +479,7 @@ mod tests {
#[test] #[test]
fn test_root_folder_add_no_op_when_not_ready() { fn test_root_folder_add_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app app
@@ -487,7 +488,7 @@ mod tests {
.root_folders .root_folders
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.add.key, DEFAULT_KEYBINDINGS.add.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -505,7 +506,7 @@ mod tests {
#[test] #[test]
fn test_refresh_root_folders_key() { fn test_refresh_root_folders_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -513,7 +514,7 @@ mod tests {
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -530,7 +531,7 @@ mod tests {
#[test] #[test]
fn test_refresh_root_folders_key_no_op_when_not_ready() { fn test_refresh_root_folders_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app app
.data .data
@@ -539,7 +540,7 @@ mod tests {
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -556,7 +557,7 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_backspace_key() { fn test_add_root_folder_prompt_backspace_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -564,7 +565,7 @@ mod tests {
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some("/nfs/test".into()); app.data.radarr_data.edit_root_folder = Some("/nfs/test".into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
@@ -580,7 +581,7 @@ mod tests {
#[test] #[test]
fn test_add_root_folder_prompt_char_key() { fn test_add_root_folder_prompt_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -588,8 +589,8 @@ mod tests {
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default()); app.data.radarr_data.edit_root_folder = Some(HorizontallyScrollableText::default());
RootFoldersHandler::with( RootFoldersHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveRadarrBlock::AddRootFolderPrompt, ActiveRadarrBlock::AddRootFolderPrompt,
None, None,
@@ -598,13 +599,13 @@ mod tests {
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.edit_root_folder.as_ref().unwrap().text, app.data.radarr_data.edit_root_folder.as_ref().unwrap().text,
"h" "a"
); );
} }
#[test] #[test]
fn test_delete_root_folder_prompt_confirm() { fn test_delete_root_folder_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
@@ -613,7 +614,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into()); app.push_navigation_stack(ActiveRadarrBlock::RootFolders.into());
app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::DeleteRootFolderPrompt.into());
RootFoldersHandler::with( RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::DeleteRootFolderPrompt, ActiveRadarrBlock::DeleteRootFolderPrompt,
@@ -644,15 +645,31 @@ mod tests {
}) })
} }
#[rstest]
fn test_root_folders_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_add_root_folder_body() { fn test_build_add_root_folder_body() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.edit_root_folder = Some("/nfs/test".into()); app.data.radarr_data.edit_root_folder = Some("/nfs/test".into());
let expected_add_root_folder_body = AddRootFolderBody { let expected_add_root_folder_body = AddRootFolderBody {
path: "/nfs/test".to_owned(), path: "/nfs/test".to_owned(),
}; };
let actual_add_root_folder_body = RootFoldersHandler::with( let actual_add_root_folder_body = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -666,14 +683,14 @@ mod tests {
#[test] #[test]
fn test_extract_root_folder_id() { fn test_extract_root_folder_id() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.root_folders .root_folders
.set_items(vec![root_folder()]); .set_items(vec![root_folder()]);
let root_folder_id = RootFoldersHandler::with( let root_folder_id = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -686,10 +703,10 @@ mod tests {
#[test] #[test]
fn test_root_folders_handler_not_ready_when_loading() { fn test_root_folders_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = RootFoldersHandler::with( let handler = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -701,10 +718,10 @@ mod tests {
#[test] #[test]
fn test_root_folders_handler_not_ready_when_root_folders_is_empty() { fn test_root_folders_handler_not_ready_when_root_folders_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = RootFoldersHandler::with( let handler = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
@@ -716,7 +733,7 @@ mod tests {
#[test] #[test]
fn test_root_folders_handler_ready_when_not_loading_and_root_folders_is_not_empty() { fn test_root_folders_handler_ready_when_not_loading_and_root_folders_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
@@ -724,7 +741,7 @@ mod tests {
.radarr_data .radarr_data
.root_folders .root_folders
.set_items(vec![RootFolder::default()]); .set_items(vec![RootFolder::default()]);
let handler = RootFoldersHandler::with( let handler = RootFoldersHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::RootFolders, ActiveRadarrBlock::RootFolders,
+12 -8
View File
@@ -1,9 +1,9 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::radarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler; use crate::handlers::radarr_handlers::system::system_details_handler::SystemDetailsHandler;
use crate::handlers::{handle_clear_errors, KeyEventHandler}; use crate::handlers::{handle_clear_errors, KeyEventHandler};
use crate::matches_key;
use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock; use crate::models::servarr_data::radarr::radarr_data::ActiveRadarrBlock;
use crate::models::Scrollable; use crate::models::Scrollable;
@@ -24,7 +24,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
fn handle(&mut self) { fn handle(&mut self) {
match self.active_radarr_block { match self.active_radarr_block {
_ if SystemDetailsHandler::accepts(self.active_radarr_block) => { _ if SystemDetailsHandler::accepts(self.active_radarr_block) => {
SystemDetailsHandler::with(self.key, self.app, self.active_radarr_block, self.context) SystemDetailsHandler::new(self.key, self.app, self.active_radarr_block, self.context)
.handle() .handle()
} }
_ => self.handle_key_event(), _ => self.handle_key_event(),
@@ -35,7 +35,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
SystemDetailsHandler::accepts(active_block) || active_block == ActiveRadarrBlock::System SystemDetailsHandler::accepts(active_block) || active_block == ActiveRadarrBlock::System
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -86,15 +90,15 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
if self.active_radarr_block == ActiveRadarrBlock::System { if self.active_radarr_block == ActiveRadarrBlock::System {
let key = self.key; let key = self.key;
match self.key { match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ if key == DEFAULT_KEYBINDINGS.events.key => { _ if matches_key!(events, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::SystemQueuedEvents.into()); .push_navigation_stack(ActiveRadarrBlock::SystemQueuedEvents.into());
} }
_ if key == DEFAULT_KEYBINDINGS.logs.key => { _ if matches_key!(logs, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::SystemLogs.into()); .push_navigation_stack(ActiveRadarrBlock::SystemLogs.into());
@@ -106,12 +110,12 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemHandler<'a, 'b
.set_items(self.app.data.radarr_data.logs.items.to_vec()); .set_items(self.app.data.radarr_data.logs.items.to_vec());
self.app.data.radarr_data.log_details.scroll_to_bottom(); self.app.data.radarr_data.log_details.scroll_to_bottom();
} }
_ if key == DEFAULT_KEYBINDINGS.tasks.key => { _ if matches_key!(tasks, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); .push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
} }
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into()); .push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into());
@@ -1,7 +1,7 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::matches_key;
use crate::models::radarr_models::RadarrTaskName; use crate::models::radarr_models::RadarrTaskName;
use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS}; use crate::models::servarr_data::radarr::radarr_data::{ActiveRadarrBlock, SYSTEM_DETAILS_BLOCKS};
use crate::models::stateful_list::StatefulList; use crate::models::stateful_list::StatefulList;
@@ -19,7 +19,7 @@ pub(super) struct SystemDetailsHandler<'a, 'b> {
_context: Option<ActiveRadarrBlock>, _context: Option<ActiveRadarrBlock>,
} }
impl<'a, 'b> SystemDetailsHandler<'a, 'b> { impl SystemDetailsHandler<'_, '_> {
fn extract_task_name(&self) -> RadarrTaskName { fn extract_task_name(&self) -> RadarrTaskName {
self self
.app .app
@@ -36,7 +36,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
SYSTEM_DETAILS_BLOCKS.contains(&active_block) SYSTEM_DETAILS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveRadarrBlock, active_block: ActiveRadarrBlock,
@@ -114,7 +118,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
match self.active_radarr_block { match self.active_radarr_block {
ActiveRadarrBlock::SystemLogs => match self.key { ActiveRadarrBlock::SystemLogs => match self.key {
_ if key == DEFAULT_KEYBINDINGS.left.key => { _ if matches_key!(left, key) => {
self self
.app .app
.data .data
@@ -124,7 +128,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
.iter() .iter()
.for_each(|log| log.scroll_right()); .for_each(|log| log.scroll_right());
} }
_ if key == DEFAULT_KEYBINDINGS.right.key => { _ if matches_key!(right, key) => {
self self
.app .app
.data .data
@@ -178,14 +182,13 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveRadarrBlock> for SystemDetailsHandler
} }
fn handle_char_key_event(&mut self) { fn handle_char_key_event(&mut self) {
if SYSTEM_DETAILS_BLOCKS.contains(&self.active_radarr_block) if SYSTEM_DETAILS_BLOCKS.contains(&self.active_radarr_block) && matches_key!(refresh, self.key)
&& self.key == DEFAULT_KEYBINDINGS.refresh.key
{ {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
if self.active_radarr_block == ActiveRadarrBlock::SystemTaskStartConfirmPrompt if self.active_radarr_block == ActiveRadarrBlock::SystemTaskStartConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.radarr_data.prompt_confirm = true; self.app.data.radarr_data.prompt_confirm = true;
self.app.data.radarr_data.prompt_confirm_action = self.app.data.radarr_data.prompt_confirm_action =
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -39,7 +40,7 @@ mod tests {
fn test_log_details_scroll_no_op_when_not_ready( fn test_log_details_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app app
.data .data
@@ -51,14 +52,14 @@ mod tests {
text text
)); ));
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemLogs, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemLogs, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text, app.data.radarr_data.log_details.current_selection().text,
"Test 1" "Test 1"
); );
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemLogs, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemLogs, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.log_details.current_selection().text, app.data.radarr_data.log_details.current_selection().text,
@@ -70,7 +71,7 @@ mod tests {
fn test_tasks_scroll( fn test_tasks_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app app
.data .data
@@ -78,14 +79,14 @@ mod tests {
.tasks .tasks
.set_items(simple_stateful_iterable_vec!(RadarrTask, String, name)); .set_items(simple_stateful_iterable_vec!(RadarrTask, String, name));
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name, app.data.radarr_data.tasks.current_selection().name,
"Test 2" "Test 2"
); );
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name, app.data.radarr_data.tasks.current_selection().name,
@@ -97,7 +98,7 @@ mod tests {
fn test_tasks_scroll_no_op_when_not_ready( fn test_tasks_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app app
@@ -106,14 +107,14 @@ mod tests {
.tasks .tasks
.set_items(simple_stateful_iterable_vec!(RadarrTask, String, name)); .set_items(simple_stateful_iterable_vec!(RadarrTask, String, name));
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name, app.data.radarr_data.tasks.current_selection().name,
"Test 1" "Test 1"
); );
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle(); SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemTasks, None).handle();
assert_str_eq!( assert_str_eq!(
app.data.radarr_data.tasks.current_selection().name, app.data.radarr_data.tasks.current_selection().name,
@@ -125,7 +126,7 @@ mod tests {
fn test_queued_events_scroll( fn test_queued_events_scroll(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app app
.data .data
@@ -133,7 +134,7 @@ mod tests {
.queued_events .queued_events
.set_items(simple_stateful_iterable_vec!(QueueEvent, String, name)); .set_items(simple_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None) SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None)
.handle(); .handle();
assert_str_eq!( assert_str_eq!(
@@ -141,7 +142,7 @@ mod tests {
"Test 2" "Test 2"
); );
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None) SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None)
.handle(); .handle();
assert_str_eq!( assert_str_eq!(
@@ -154,7 +155,7 @@ mod tests {
fn test_queued_events_scroll_no_op_when_not_ready( fn test_queued_events_scroll_no_op_when_not_ready(
#[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.down.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
app app
@@ -163,7 +164,7 @@ mod tests {
.queued_events .queued_events
.set_items(simple_stateful_iterable_vec!(QueueEvent, String, name)); .set_items(simple_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None) SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None)
.handle(); .handle();
assert_str_eq!( assert_str_eq!(
@@ -171,7 +172,7 @@ mod tests {
"Test 1" "Test 1"
); );
SystemDetailsHandler::with(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None) SystemDetailsHandler::new(key, &mut app, ActiveRadarrBlock::SystemQueuedEvents, None)
.handle(); .handle();
assert_str_eq!( assert_str_eq!(
@@ -182,10 +183,10 @@ mod tests {
#[test] #[test]
fn test_system_updates_scroll() { fn test_system_updates_scroll() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.up.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -195,7 +196,7 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 0); assert_eq!(app.data.radarr_data.updates.offset, 0);
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.down.key, DEFAULT_KEYBINDINGS.down.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -208,11 +209,11 @@ mod tests {
#[test] #[test]
fn test_system_updates_scroll_no_op_when_not_ready() { fn test_system_updates_scroll_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.up.key, DEFAULT_KEYBINDINGS.up.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -222,7 +223,7 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 0); assert_eq!(app.data.radarr_data.updates.offset, 0);
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.down.key, DEFAULT_KEYBINDINGS.down.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -254,7 +255,7 @@ mod tests {
#[test] #[test]
fn test_log_details_home_end_no_op_when_not_ready() { fn test_log_details_home_end_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app app
.data .data
@@ -266,7 +267,7 @@ mod tests {
text text
)); ));
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemLogs, ActiveRadarrBlock::SystemLogs,
@@ -279,7 +280,7 @@ mod tests {
"Test 1" "Test 1"
); );
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemLogs, ActiveRadarrBlock::SystemLogs,
@@ -295,7 +296,7 @@ mod tests {
#[test] #[test]
fn test_tasks_home_end() { fn test_tasks_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned()); ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app app
@@ -304,7 +305,7 @@ mod tests {
.tasks .tasks
.set_items(extended_stateful_iterable_vec!(RadarrTask, String, name)); .set_items(extended_stateful_iterable_vec!(RadarrTask, String, name));
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -317,7 +318,7 @@ mod tests {
"Test 3" "Test 3"
); );
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -333,7 +334,7 @@ mod tests {
#[test] #[test]
fn test_tasks_home_end_no_op_when_not_ready() { fn test_tasks_home_end_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned()); ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
@@ -343,7 +344,7 @@ mod tests {
.tasks .tasks
.set_items(extended_stateful_iterable_vec!(RadarrTask, String, name)); .set_items(extended_stateful_iterable_vec!(RadarrTask, String, name));
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -356,7 +357,7 @@ mod tests {
"Test 1" "Test 1"
); );
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -372,7 +373,7 @@ mod tests {
#[test] #[test]
fn test_queued_events_home_end() { fn test_queued_events_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned()); ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
app app
@@ -381,7 +382,7 @@ mod tests {
.queued_events .queued_events
.set_items(extended_stateful_iterable_vec!(QueueEvent, String, name)); .set_items(extended_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemQueuedEvents, ActiveRadarrBlock::SystemQueuedEvents,
@@ -394,7 +395,7 @@ mod tests {
"Test 3" "Test 3"
); );
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemQueuedEvents, ActiveRadarrBlock::SystemQueuedEvents,
@@ -410,7 +411,7 @@ mod tests {
#[test] #[test]
fn test_queued_events_home_end_no_op_when_not_ready() { fn test_queued_events_home_end_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = app.data.radarr_data.updates =
ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned()); ScrollableText::with_string("Test 1\nTest 2\nTest 3".to_owned());
@@ -420,7 +421,7 @@ mod tests {
.queued_events .queued_events
.set_items(extended_stateful_iterable_vec!(QueueEvent, String, name)); .set_items(extended_stateful_iterable_vec!(QueueEvent, String, name));
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemQueuedEvents, ActiveRadarrBlock::SystemQueuedEvents,
@@ -433,7 +434,7 @@ mod tests {
"Test 1" "Test 1"
); );
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemQueuedEvents, ActiveRadarrBlock::SystemQueuedEvents,
@@ -449,10 +450,10 @@ mod tests {
#[test] #[test]
fn test_system_updates_home_end() { fn test_system_updates_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -462,7 +463,7 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 1); assert_eq!(app.data.radarr_data.updates.offset, 1);
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -475,11 +476,11 @@ mod tests {
#[test] #[test]
fn test_system_updates_home_end_no_op_when_not_ready() { fn test_system_updates_home_end_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test 1\nTest 2".to_owned());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -489,7 +490,7 @@ mod tests {
assert_eq!(app.data.radarr_data.updates.offset, 0); assert_eq!(app.data.radarr_data.updates.offset, 0);
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -510,14 +511,14 @@ mod tests {
#[test] #[test]
fn test_handle_log_details_left_right() { fn test_handle_log_details_left_right() {
let active_radarr_block = ActiveRadarrBlock::SystemLogs; let active_radarr_block = ActiveRadarrBlock::SystemLogs;
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.radarr_data .radarr_data
.log_details .log_details
.set_items(vec!["t1".into(), "t22".into()]); .set_items(vec!["t1".into(), "t22".into()]);
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -528,7 +529,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "t1"); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "t1");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "t22"); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "t22");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -539,7 +540,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "1"); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "1");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "22"); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "22");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -550,7 +551,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), ""); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "2"); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "2");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -561,7 +562,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), ""); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), ""); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -572,7 +573,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), ""); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), ""); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -583,7 +584,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "1"); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "1");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "2"); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "2");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -594,7 +595,7 @@ mod tests {
assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "t1"); assert_eq!(app.data.radarr_data.log_details.items[0].to_string(), "t1");
assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "22"); assert_eq!(app.data.radarr_data.log_details.items[1].to_string(), "22");
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -610,9 +611,9 @@ mod tests {
fn test_left_right_prompt_toggle( fn test_left_right_prompt_toggle(
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
SystemDetailsHandler::with( SystemDetailsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -622,7 +623,7 @@ mod tests {
assert!(app.data.radarr_data.prompt_confirm); assert!(app.data.radarr_data.prompt_confirm);
SystemDetailsHandler::with( SystemDetailsHandler::new(
key, key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -645,10 +646,10 @@ mod tests {
#[test] #[test]
fn test_system_tasks_submit() { fn test_system_tasks_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
SystemDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None) SystemDetailsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None)
.handle(); .handle();
assert_eq!( assert_eq!(
@@ -659,12 +660,12 @@ mod tests {
#[test] #[test]
fn test_system_tasks_submit_no_op_when_not_ready() { fn test_system_tasks_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
SystemDetailsHandler::with(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None) SystemDetailsHandler::new(SUBMIT_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None)
.handle(); .handle();
assert_eq!( assert_eq!(
@@ -675,7 +676,7 @@ mod tests {
#[test] #[test]
fn test_system_tasks_start_task_prompt_confirm_submit() { fn test_system_tasks_start_task_prompt_confirm_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
app.data.radarr_data.tasks.set_items(vec![RadarrTask { app.data.radarr_data.tasks.set_items(vec![RadarrTask {
@@ -685,7 +686,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
SystemDetailsHandler::with( SystemDetailsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -706,12 +707,12 @@ mod tests {
#[test] #[test]
fn test_system_tasks_start_task_prompt_decline_submit() { fn test_system_tasks_start_task_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
SystemDetailsHandler::with( SystemDetailsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -739,7 +740,7 @@ mod tests {
#[rstest] #[rstest]
fn test_esc_system_logs(#[values(true, false)] is_ready: bool) { fn test_esc_system_logs(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app app
.data .data
@@ -754,7 +755,7 @@ mod tests {
.log_details .log_details
.set_items(vec![HorizontallyScrollableText::default()]); .set_items(vec![HorizontallyScrollableText::default()]);
SystemDetailsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::SystemLogs, None).handle(); SystemDetailsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::SystemLogs, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into());
assert!(app.data.radarr_data.log_details.items.is_empty()); assert!(app.data.radarr_data.log_details.items.is_empty());
@@ -762,7 +763,7 @@ mod tests {
#[rstest] #[rstest]
fn test_esc_system_tasks(#[values(true, false)] is_ready: bool) { fn test_esc_system_tasks(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
@@ -772,14 +773,14 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemDetailsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None).handle(); SystemDetailsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::SystemTasks, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into());
} }
#[rstest] #[rstest]
fn test_esc_system_queued_events(#[values(true, false)] is_ready: bool) { fn test_esc_system_queued_events(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemQueuedEvents.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemQueuedEvents.into());
@@ -789,7 +790,7 @@ mod tests {
.queued_events .queued_events
.set_items(vec![QueueEvent::default()]); .set_items(vec![QueueEvent::default()]);
SystemDetailsHandler::with( SystemDetailsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::SystemQueuedEvents, ActiveRadarrBlock::SystemQueuedEvents,
@@ -802,25 +803,24 @@ mod tests {
#[rstest] #[rstest]
fn test_esc_system_updates(#[values(true, false)] is_ready: bool) { fn test_esc_system_updates(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemUpdates.into());
SystemDetailsHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::SystemUpdates, None) SystemDetailsHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::SystemUpdates, None).handle();
.handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into());
} }
#[test] #[test]
fn test_system_tasks_start_task_prompt_esc() { fn test_system_tasks_start_task_prompt_esc() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
app.data.radarr_data.prompt_confirm = true; app.data.radarr_data.prompt_confirm = true;
SystemDetailsHandler::with( SystemDetailsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -854,11 +854,11 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -880,12 +880,12 @@ mod tests {
)] )]
active_radarr_block: ActiveRadarrBlock, active_radarr_block: ActiveRadarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.push_navigation_stack(active_radarr_block.into()); app.push_navigation_stack(active_radarr_block.into());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
active_radarr_block, active_radarr_block,
@@ -899,7 +899,7 @@ mod tests {
#[test] #[test]
fn test_system_tasks_start_task_prompt_confirm() { fn test_system_tasks_start_task_prompt_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
app.data.radarr_data.tasks.set_items(vec![RadarrTask { app.data.radarr_data.tasks.set_items(vec![RadarrTask {
task_name: RadarrTaskName::default(), task_name: RadarrTaskName::default(),
@@ -908,7 +908,7 @@ mod tests {
app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTasks.into());
app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into()); app.push_navigation_stack(ActiveRadarrBlock::SystemTaskStartConfirmPrompt.into());
SystemDetailsHandler::with( SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTaskStartConfirmPrompt, ActiveRadarrBlock::SystemTaskStartConfirmPrompt,
@@ -939,15 +939,31 @@ mod tests {
}) })
} }
#[rstest]
fn test_system_details_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_task_name() { fn test_extract_task_name() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.tasks.set_items(vec![RadarrTask { app.data.radarr_data.tasks.set_items(vec![RadarrTask {
task_name: RadarrTaskName::default(), task_name: RadarrTaskName::default(),
..RadarrTask::default() ..RadarrTask::default()
}]); }]);
let task_name = SystemDetailsHandler::with( let task_name = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -960,10 +976,10 @@ mod tests {
#[test] #[test]
fn test_system_details_handler_not_ready_when_loading() { fn test_system_details_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let handler = SystemDetailsHandler::with( let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -975,10 +991,10 @@ mod tests {
#[test] #[test]
fn test_system_details_handler_not_ready_when_log_details_and_updates_and_tasks_are_empty() { fn test_system_details_handler_not_ready_when_log_details_and_updates_and_tasks_are_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
let handler = SystemDetailsHandler::with( let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -990,7 +1006,7 @@ mod tests {
#[test] #[test]
fn test_system_details_handler_ready_when_not_loading_and_log_details_is_not_empty() { fn test_system_details_handler_ready_when_not_loading_and_log_details_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -998,7 +1014,7 @@ mod tests {
.log_details .log_details
.set_items(vec![HorizontallyScrollableText::default()]); .set_items(vec![HorizontallyScrollableText::default()]);
let handler = SystemDetailsHandler::with( let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -1010,7 +1026,7 @@ mod tests {
#[test] #[test]
fn test_system_details_handler_ready_when_not_loading_and_tasks_is_not_empty() { fn test_system_details_handler_ready_when_not_loading_and_tasks_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -1018,7 +1034,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
let handler = SystemDetailsHandler::with( let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemTasks, ActiveRadarrBlock::SystemTasks,
@@ -1030,11 +1046,11 @@ mod tests {
#[test] #[test]
fn test_system_details_handler_ready_when_not_loading_and_updates_is_not_empty() { fn test_system_details_handler_ready_when_not_loading_and_updates_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned()); app.data.radarr_data.updates = ScrollableText::with_string("Test".to_owned());
let handler = SystemDetailsHandler::with( let handler = SystemDetailsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveRadarrBlock::SystemUpdates, ActiveRadarrBlock::SystemUpdates,
@@ -22,11 +22,11 @@ mod tests {
#[rstest] #[rstest]
fn test_system_tab_left(#[values(true, false)] is_ready: bool) { fn test_system_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(6); app.data.radarr_data.main_tabs.set_index(6);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -43,11 +43,11 @@ mod tests {
#[rstest] #[rstest]
fn test_system_tab_right(#[values(true, false)] is_ready: bool) { fn test_system_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.radarr_data.main_tabs.set_index(6); app.data.radarr_data.main_tabs.set_index(6);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -72,13 +72,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_loading: bool) { fn test_default_esc(#[values(true, false)] is_loading: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_loading; app.is_loading = is_loading;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
SystemHandler::with(ESC_KEY, &mut app, ActiveRadarrBlock::System, None).handle(); SystemHandler::new(ESC_KEY, &mut app, ActiveRadarrBlock::System, None).handle();
assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into()); assert_eq!(app.get_current_route(), ActiveRadarrBlock::System.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -94,7 +94,7 @@ mod tests {
#[test] #[test]
fn test_update_system_key() { fn test_update_system_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"), HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"), HorizontallyScrollableText::from("test 2"),
@@ -110,7 +110,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -126,7 +126,7 @@ mod tests {
#[test] #[test]
fn test_update_system_key_no_op_if_not_ready() { fn test_update_system_key_no_op_if_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
@@ -144,7 +144,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -157,7 +157,7 @@ mod tests {
#[test] #[test]
fn test_queued_events_key() { fn test_queued_events_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"), HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"), HorizontallyScrollableText::from("test 2"),
@@ -173,7 +173,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.events.key, DEFAULT_KEYBINDINGS.events.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -189,7 +189,7 @@ mod tests {
#[test] #[test]
fn test_queued_events_key_no_op_if_not_ready() { fn test_queued_events_key_no_op_if_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
@@ -207,7 +207,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.events.key, DEFAULT_KEYBINDINGS.events.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -220,7 +220,7 @@ mod tests {
#[test] #[test]
fn test_refresh_system_key() { fn test_refresh_system_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"), HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"), HorizontallyScrollableText::from("test 2"),
@@ -237,7 +237,7 @@ mod tests {
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -251,7 +251,7 @@ mod tests {
#[test] #[test]
fn test_refresh_system_key_no_op_if_not_ready() { fn test_refresh_system_key_no_op_if_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
@@ -270,7 +270,7 @@ mod tests {
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -284,7 +284,7 @@ mod tests {
#[test] #[test]
fn test_logs_key() { fn test_logs_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"), HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"), HorizontallyScrollableText::from("test 2"),
@@ -300,7 +300,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.logs.key, DEFAULT_KEYBINDINGS.logs.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -324,7 +324,7 @@ mod tests {
#[test] #[test]
fn test_logs_key_no_op_when_not_ready() { fn test_logs_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
@@ -342,7 +342,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.logs.key, DEFAULT_KEYBINDINGS.logs.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -356,7 +356,7 @@ mod tests {
#[test] #[test]
fn test_tasks_key() { fn test_tasks_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
HorizontallyScrollableText::from("test 1"), HorizontallyScrollableText::from("test 1"),
HorizontallyScrollableText::from("test 2"), HorizontallyScrollableText::from("test 2"),
@@ -372,7 +372,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.tasks.key, DEFAULT_KEYBINDINGS.tasks.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -388,7 +388,7 @@ mod tests {
#[test] #[test]
fn test_tasks_key_no_op_when_not_ready() { fn test_tasks_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveRadarrBlock::System.into()); app.push_navigation_stack(ActiveRadarrBlock::System.into());
app.data.radarr_data.logs.set_items(vec![ app.data.radarr_data.logs.set_items(vec![
@@ -406,7 +406,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
SystemHandler::with( SystemHandler::new(
DEFAULT_KEYBINDINGS.tasks.key, DEFAULT_KEYBINDINGS.tasks.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -450,12 +450,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_system_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveRadarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_system_handler_is_not_ready_when_loading() { fn test_system_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
let system_handler = SystemHandler::with( let system_handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -467,7 +483,7 @@ mod tests {
#[test] #[test]
fn test_system_handler_is_not_ready_when_logs_is_empty() { fn test_system_handler_is_not_ready_when_logs_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app app
.data .data
@@ -480,7 +496,7 @@ mod tests {
.queued_events .queued_events
.set_items(vec![QueueEvent::default()]); .set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with( let system_handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -492,7 +508,7 @@ mod tests {
#[test] #[test]
fn test_system_handler_is_not_ready_when_tasks_is_empty() { fn test_system_handler_is_not_ready_when_tasks_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]); app.data.radarr_data.logs.set_items(vec!["test".into()]);
app app
@@ -501,7 +517,7 @@ mod tests {
.queued_events .queued_events
.set_items(vec![QueueEvent::default()]); .set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with( let system_handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -513,7 +529,7 @@ mod tests {
#[test] #[test]
fn test_system_handler_is_not_ready_when_queued_events_is_empty() { fn test_system_handler_is_not_ready_when_queued_events_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]); app.data.radarr_data.logs.set_items(vec!["test".into()]);
app app
@@ -522,7 +538,7 @@ mod tests {
.tasks .tasks
.set_items(vec![RadarrTask::default()]); .set_items(vec![RadarrTask::default()]);
let system_handler = SystemHandler::with( let system_handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -534,7 +550,7 @@ mod tests {
#[test] #[test]
fn test_system_handler_is_ready_when_all_required_tables_are_not_empty() { fn test_system_handler_is_ready_when_all_required_tables_are_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = false; app.is_loading = false;
app.data.radarr_data.logs.set_items(vec!["test".into()]); app.data.radarr_data.logs.set_items(vec!["test".into()]);
app app
@@ -548,7 +564,7 @@ mod tests {
.queued_events .queued_events
.set_items(vec![QueueEvent::default()]); .set_items(vec![QueueEvent::default()]);
let system_handler = SystemHandler::with( let system_handler = SystemHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveRadarrBlock::System, ActiveRadarrBlock::System,
@@ -4,6 +4,7 @@ mod tests {
use chrono::DateTime; use chrono::DateTime;
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -24,11 +25,11 @@ mod tests {
#[test] #[test]
fn test_delete_blocklist_item_prompt() { fn test_delete_blocklist_item_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(DELETE_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); BlocklistHandler::new(DELETE_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -38,12 +39,12 @@ mod tests {
#[test] #[test]
fn test_delete_blocklist_item_no_op_when_not_ready() { fn test_delete_blocklist_item_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with(DELETE_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); BlocklistHandler::new(DELETE_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into());
} }
@@ -57,12 +58,12 @@ mod tests {
#[rstest] #[rstest]
fn test_blocklist_tab_left(#[values(true, false)] is_ready: bool) { fn test_blocklist_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(2); app.data.sonarr_data.main_tabs.set_index(2);
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -79,12 +80,12 @@ mod tests {
#[rstest] #[rstest]
fn test_blocklist_tab_right(#[values(true, false)] is_ready: bool) { fn test_blocklist_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(2); app.data.sonarr_data.main_tabs.set_index(2);
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -108,14 +109,14 @@ mod tests {
active_sonarr_block: ActiveSonarrBlock, active_sonarr_block: ActiveSonarrBlock,
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with(key, &mut app, active_sonarr_block, None).handle(); BlocklistHandler::new(key, &mut app, active_sonarr_block, None).handle();
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
BlocklistHandler::with(key, &mut app, active_sonarr_block, None).handle(); BlocklistHandler::new(key, &mut app, active_sonarr_block, None).handle();
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
} }
@@ -133,11 +134,11 @@ mod tests {
#[test] #[test]
fn test_blocklist_submit() { fn test_blocklist_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -147,12 +148,12 @@ mod tests {
#[test] #[test]
fn test_blocklist_submit_no_op_when_not_ready() { fn test_blocklist_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into());
} }
@@ -173,13 +174,13 @@ mod tests {
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
#[case] expected_action: SonarrEvent, #[case] expected_action: SonarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -197,12 +198,12 @@ mod tests {
)] )]
prompt_block: ActiveSonarrBlock, prompt_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
assert_eq!(app.data.sonarr_data.prompt_confirm_action, None); assert_eq!(app.data.sonarr_data.prompt_confirm_action, None);
@@ -231,12 +232,12 @@ mod tests {
#[case] base_block: ActiveSonarrBlock, #[case] base_block: ActiveSonarrBlock,
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(base_block.into()); app.push_navigation_stack(base_block.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
BlocklistHandler::with(ESC_KEY, &mut app, prompt_block, None).handle(); BlocklistHandler::new(ESC_KEY, &mut app, prompt_block, None).handle();
assert_eq!(app.get_current_route(), base_block.into()); assert_eq!(app.get_current_route(), base_block.into());
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
@@ -244,11 +245,11 @@ mod tests {
#[test] #[test]
fn test_esc_blocklist_item_details() { fn test_esc_blocklist_item_details() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.push_navigation_stack(ActiveSonarrBlock::BlocklistItemDetails.into()); app.push_navigation_stack(ActiveSonarrBlock::BlocklistItemDetails.into());
BlocklistHandler::with( BlocklistHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveSonarrBlock::BlocklistItemDetails, ActiveSonarrBlock::BlocklistItemDetails,
@@ -261,13 +262,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle(); BlocklistHandler::new(ESC_KEY, &mut app, ActiveSonarrBlock::Blocklist, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Blocklist.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -284,11 +285,11 @@ mod tests {
#[test] #[test]
fn test_refresh_blocklist_key() { fn test_refresh_blocklist_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -302,12 +303,12 @@ mod tests {
#[test] #[test]
fn test_refresh_blocklist_key_no_op_when_not_ready() { fn test_refresh_blocklist_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -321,11 +322,11 @@ mod tests {
#[test] #[test]
fn test_clear_blocklist_key() { fn test_clear_blocklist_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.clear.key, DEFAULT_KEYBINDINGS.clear.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -341,12 +342,12 @@ mod tests {
#[test] #[test]
fn test_clear_blocklist_key_no_op_when_not_ready() { fn test_clear_blocklist_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.clear.key, DEFAULT_KEYBINDINGS.clear.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -373,12 +374,12 @@ mod tests {
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
#[case] expected_action: SonarrEvent, #[case] expected_action: SonarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
BlocklistHandler::with( BlocklistHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
prompt_block, prompt_block,
@@ -513,12 +514,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_blocklist_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_blocklist_item_id() { fn test_extract_blocklist_item_id() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.blocklist.set_items(blocklist_vec()); app.data.sonarr_data.blocklist.set_items(blocklist_vec());
let blocklist_item_id = BlocklistHandler::with( let blocklist_item_id = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -531,11 +548,11 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_not_ready_when_loading() { fn test_blocklist_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.is_loading = true; app.is_loading = true;
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -547,11 +564,11 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_not_ready_when_blocklist_is_empty() { fn test_blocklist_handler_not_ready_when_blocklist_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.is_loading = false; app.is_loading = false;
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
@@ -563,7 +580,7 @@ mod tests {
#[test] #[test]
fn test_blocklist_handler_ready_when_not_loading_and_blocklist_is_not_empty() { fn test_blocklist_handler_ready_when_not_loading_and_blocklist_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into()); app.push_navigation_stack(ActiveSonarrBlock::Blocklist.into());
app.is_loading = false; app.is_loading = false;
app app
@@ -572,7 +589,7 @@ mod tests {
.blocklist .blocklist
.set_items(vec![BlocklistItem::default()]); .set_items(vec![BlocklistItem::default()]);
let handler = BlocklistHandler::with( let handler = BlocklistHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Blocklist, ActiveSonarrBlock::Blocklist,
+11 -8
View File
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
@@ -9,6 +7,7 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, BLOCKL
use crate::models::sonarr_models::BlocklistItem; use crate::models::sonarr_models::BlocklistItem;
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::network::sonarr_network::SonarrEvent; use crate::network::sonarr_network::SonarrEvent;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "blocklist_handler_tests.rs"] #[path = "blocklist_handler_tests.rs"]
@@ -21,7 +20,7 @@ pub(super) struct BlocklistHandler<'a, 'b> {
_context: Option<ActiveSonarrBlock>, _context: Option<ActiveSonarrBlock>,
} }
impl<'a, 'b> BlocklistHandler<'a, 'b> { impl BlocklistHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
blocklist, blocklist,
@@ -51,7 +50,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a,
BLOCKLIST_BLOCKS.contains(&active_block) BLOCKLIST_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveSonarrBlock, active_block: ActiveSonarrBlock,
@@ -143,10 +146,10 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a,
let key = self.key; let key = self.key;
match self.active_sonarr_block { match self.active_sonarr_block {
ActiveSonarrBlock::Blocklist => match self.key { ActiveSonarrBlock::Blocklist => match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ if key == DEFAULT_KEYBINDINGS.clear.key => { _ if matches_key!(clear, key) => {
self self
.app .app
.push_navigation_stack(ActiveSonarrBlock::BlocklistClearAllItemsPrompt.into()); .push_navigation_stack(ActiveSonarrBlock::BlocklistClearAllItemsPrompt.into());
@@ -154,7 +157,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a,
_ => (), _ => (),
}, },
ActiveSonarrBlock::DeleteBlocklistItemPrompt => { ActiveSonarrBlock::DeleteBlocklistItemPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::DeleteBlocklistItem( self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::DeleteBlocklistItem(
self.extract_blocklist_item_id(), self.extract_blocklist_item_id(),
@@ -164,7 +167,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for BlocklistHandler<'a,
} }
} }
ActiveSonarrBlock::BlocklistClearAllItemsPrompt => { ActiveSonarrBlock::BlocklistClearAllItemsPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::ClearBlocklist); self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::ClearBlocklist);
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -21,7 +22,7 @@ mod tests {
#[test] #[test]
fn test_delete_download_prompt() { fn test_delete_download_prompt() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app app
.data .data
@@ -29,7 +30,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(DELETE_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle(); DownloadsHandler::new(DELETE_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -39,7 +40,7 @@ mod tests {
#[test] #[test]
fn test_delete_download_prompt_no_op_when_not_ready() { fn test_delete_download_prompt_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app app
@@ -48,7 +49,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with(DELETE_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle(); DownloadsHandler::new(DELETE_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Downloads.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Downloads.into());
} }
@@ -62,12 +63,12 @@ mod tests {
#[rstest] #[rstest]
fn test_downloads_tab_left(#[values(true, false)] is_ready: bool) { fn test_downloads_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(1); app.data.sonarr_data.main_tabs.set_index(1);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -84,12 +85,12 @@ mod tests {
#[rstest] #[rstest]
fn test_downloads_tab_right(#[values(true, false)] is_ready: bool) { fn test_downloads_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(1); app.data.sonarr_data.main_tabs.set_index(1);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -113,14 +114,14 @@ mod tests {
active_sonarr_block: ActiveSonarrBlock, active_sonarr_block: ActiveSonarrBlock,
#[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key, #[values(DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.right.key)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
DownloadsHandler::with(key, &mut app, active_sonarr_block, None).handle(); DownloadsHandler::new(key, &mut app, active_sonarr_block, None).handle();
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
DownloadsHandler::with(key, &mut app, active_sonarr_block, None).handle(); DownloadsHandler::new(key, &mut app, active_sonarr_block, None).handle();
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
} }
@@ -152,7 +153,7 @@ mod tests {
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
#[case] expected_action: SonarrEvent, #[case] expected_action: SonarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
@@ -162,7 +163,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
assert_eq!( assert_eq!(
@@ -179,7 +180,7 @@ mod tests {
#[case] base_route: ActiveSonarrBlock, #[case] base_route: ActiveSonarrBlock,
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
@@ -188,7 +189,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with(SUBMIT_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(SUBMIT_KEY, &mut app, prompt_block, None).handle();
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
assert_eq!(app.data.sonarr_data.prompt_confirm_action, None); assert_eq!(app.data.sonarr_data.prompt_confirm_action, None);
@@ -211,12 +212,12 @@ mod tests {
#[case] base_block: ActiveSonarrBlock, #[case] base_block: ActiveSonarrBlock,
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(base_block.into()); app.push_navigation_stack(base_block.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
DownloadsHandler::with(ESC_KEY, &mut app, prompt_block, None).handle(); DownloadsHandler::new(ESC_KEY, &mut app, prompt_block, None).handle();
assert_eq!(app.get_current_route(), base_block.into()); assert_eq!(app.get_current_route(), base_block.into());
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
@@ -224,13 +225,13 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
DownloadsHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle(); DownloadsHandler::new(ESC_KEY, &mut app, ActiveSonarrBlock::Downloads, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Downloads.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Downloads.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -247,7 +248,7 @@ mod tests {
#[test] #[test]
fn test_update_downloads_key() { fn test_update_downloads_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app app
.data .data
@@ -255,7 +256,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -271,7 +272,7 @@ mod tests {
#[test] #[test]
fn test_update_downloads_key_no_op_when_not_ready() { fn test_update_downloads_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app app
@@ -280,7 +281,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.update.key, DEFAULT_KEYBINDINGS.update.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -293,7 +294,7 @@ mod tests {
#[test] #[test]
fn test_refresh_downloads_key() { fn test_refresh_downloads_key() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
@@ -301,7 +302,7 @@ mod tests {
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -315,7 +316,7 @@ mod tests {
#[test] #[test]
fn test_refresh_downloads_key_no_op_when_not_ready() { fn test_refresh_downloads_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app app
@@ -324,7 +325,7 @@ mod tests {
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -352,7 +353,7 @@ mod tests {
#[case] prompt_block: ActiveSonarrBlock, #[case] prompt_block: ActiveSonarrBlock,
#[case] expected_action: SonarrEvent, #[case] expected_action: SonarrEvent,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
@@ -361,7 +362,7 @@ mod tests {
app.push_navigation_stack(base_route.into()); app.push_navigation_stack(base_route.into());
app.push_navigation_stack(prompt_block.into()); app.push_navigation_stack(prompt_block.into());
DownloadsHandler::with( DownloadsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
prompt_block, prompt_block,
@@ -389,16 +390,32 @@ mod tests {
}) })
} }
#[rstest]
fn test_downloads_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_extract_download_id() { fn test_extract_download_id() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
.downloads .downloads
.set_items(vec![download_record()]); .set_items(vec![download_record()]);
let download_id = DownloadsHandler::with( let download_id = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -411,11 +428,11 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_not_ready_when_loading() { fn test_downloads_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.is_loading = true; app.is_loading = true;
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -427,11 +444,11 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_not_ready_when_downloads_is_empty() { fn test_downloads_handler_not_ready_when_downloads_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.is_loading = false; app.is_loading = false;
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
@@ -443,7 +460,7 @@ mod tests {
#[test] #[test]
fn test_downloads_handler_ready_when_not_loading_and_downloads_is_not_empty() { fn test_downloads_handler_ready_when_not_loading_and_downloads_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Downloads.into()); app.push_navigation_stack(ActiveSonarrBlock::Downloads.into());
app.is_loading = false; app.is_loading = false;
@@ -452,7 +469,7 @@ mod tests {
.sonarr_data .sonarr_data
.downloads .downloads
.set_items(vec![DownloadRecord::default()]); .set_items(vec![DownloadRecord::default()]);
let handler = DownloadsHandler::with( let handler = DownloadsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::Downloads, ActiveSonarrBlock::Downloads,
+11 -8
View File
@@ -1,13 +1,12 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_clear_errors, handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, DOWNLOADS_BLOCKS};
use crate::models::sonarr_models::DownloadRecord; use crate::models::sonarr_models::DownloadRecord;
use crate::network::sonarr_network::SonarrEvent; use crate::network::sonarr_network::SonarrEvent;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "downloads_handler_tests.rs"] #[path = "downloads_handler_tests.rs"]
@@ -20,7 +19,7 @@ pub(super) struct DownloadsHandler<'a, 'b> {
_context: Option<ActiveSonarrBlock>, _context: Option<ActiveSonarrBlock>,
} }
impl<'a, 'b> DownloadsHandler<'a, 'b> { impl DownloadsHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
downloads, downloads,
@@ -47,7 +46,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DownloadsHandler<'a,
DOWNLOADS_BLOCKS.contains(&active_block) DOWNLOADS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveSonarrBlock, active_block: ActiveSonarrBlock,
@@ -130,18 +133,18 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DownloadsHandler<'a,
let key = self.key; let key = self.key;
match self.active_sonarr_block { match self.active_sonarr_block {
ActiveSonarrBlock::Downloads => match self.key { ActiveSonarrBlock::Downloads => match self.key {
_ if key == DEFAULT_KEYBINDINGS.update.key => { _ if matches_key!(update, key) => {
self self
.app .app
.push_navigation_stack(ActiveSonarrBlock::UpdateDownloadsPrompt.into()); .push_navigation_stack(ActiveSonarrBlock::UpdateDownloadsPrompt.into());
} }
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ => (), _ => (),
}, },
ActiveSonarrBlock::DeleteDownloadPrompt => { ActiveSonarrBlock::DeleteDownloadPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = self.app.data.sonarr_data.prompt_confirm_action =
Some(SonarrEvent::DeleteDownload(self.extract_download_id())); Some(SonarrEvent::DeleteDownload(self.extract_download_id()));
@@ -150,7 +153,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for DownloadsHandler<'a,
} }
} }
ActiveSonarrBlock::UpdateDownloadsPrompt => { ActiveSonarrBlock::UpdateDownloadsPrompt => {
if key == DEFAULT_KEYBINDINGS.confirm.key { if matches_key!(confirm, key) {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::UpdateDownloads); self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::UpdateDownloads);
@@ -4,6 +4,7 @@ mod tests {
use chrono::DateTime; use chrono::DateTime;
use pretty_assertions::{assert_eq, assert_str_eq}; use pretty_assertions::{assert_eq, assert_str_eq};
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -23,12 +24,12 @@ mod tests {
#[rstest] #[rstest]
fn test_history_tab_left(#[values(true, false)] is_ready: bool) { fn test_history_tab_left(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(3); app.data.sonarr_data.main_tabs.set_index(3);
HistoryHandler::with( HistoryHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -45,12 +46,12 @@ mod tests {
#[rstest] #[rstest]
fn test_history_tab_right(#[values(true, false)] is_ready: bool) { fn test_history_tab_right(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.is_loading = is_ready; app.is_loading = is_ready;
app.data.sonarr_data.main_tabs.set_index(3); app.data.sonarr_data.main_tabs.set_index(3);
HistoryHandler::with( HistoryHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -78,11 +79,11 @@ mod tests {
#[test] #[test]
fn test_history_submit() { fn test_history_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.history.set_items(history_vec()); app.data.sonarr_data.history.set_items(history_vec());
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::History, None).handle(); HistoryHandler::new(SUBMIT_KEY, &mut app, ActiveSonarrBlock::History, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -92,12 +93,12 @@ mod tests {
#[test] #[test]
fn test_history_submit_no_op_when_not_ready() { fn test_history_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.history.set_items(history_vec()); app.data.sonarr_data.history.set_items(history_vec());
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
HistoryHandler::with(SUBMIT_KEY, &mut app, ActiveSonarrBlock::History, None).handle(); HistoryHandler::new(SUBMIT_KEY, &mut app, ActiveSonarrBlock::History, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into());
} }
@@ -115,7 +116,7 @@ mod tests {
#[test] #[test]
fn test_esc_history_item_details() { fn test_esc_history_item_details() {
let mut app = App::default(); let mut app = App::test_default();
app app
.data .data
.sonarr_data .sonarr_data
@@ -124,7 +125,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.push_navigation_stack(ActiveSonarrBlock::HistoryItemDetails.into()); app.push_navigation_stack(ActiveSonarrBlock::HistoryItemDetails.into());
HistoryHandler::with( HistoryHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveSonarrBlock::HistoryItemDetails, ActiveSonarrBlock::HistoryItemDetails,
@@ -137,7 +138,7 @@ mod tests {
#[rstest] #[rstest]
fn test_default_esc(#[values(true, false)] is_ready: bool) { fn test_default_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.error = "test error".to_owned().into(); app.error = "test error".to_owned().into();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
@@ -149,7 +150,7 @@ mod tests {
.history .history
.set_items(vec![SonarrHistoryItem::default()]); .set_items(vec![SonarrHistoryItem::default()]);
HistoryHandler::with(ESC_KEY, &mut app, ActiveSonarrBlock::History, None).handle(); HistoryHandler::new(ESC_KEY, &mut app, ActiveSonarrBlock::History, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::History.into());
assert!(app.error.text.is_empty()); assert!(app.error.text.is_empty());
@@ -163,11 +164,11 @@ mod tests {
#[test] #[test]
fn test_refresh_history_key() { fn test_refresh_history_key() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.history.set_items(history_vec()); app.data.sonarr_data.history.set_items(history_vec());
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
HistoryHandler::with( HistoryHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -181,12 +182,12 @@ mod tests {
#[test] #[test]
fn test_refresh_history_key_no_op_when_not_ready() { fn test_refresh_history_key_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.history.set_items(history_vec()); app.data.sonarr_data.history.set_items(history_vec());
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
HistoryHandler::with( HistoryHandler::new(
DEFAULT_KEYBINDINGS.refresh.key, DEFAULT_KEYBINDINGS.refresh.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -306,13 +307,29 @@ mod tests {
}) })
} }
#[rstest]
fn test_history_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = HistoryHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_history_handler_not_ready_when_loading() { fn test_history_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.is_loading = true; app.is_loading = true;
let handler = HistoryHandler::with( let handler = HistoryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -324,11 +341,11 @@ mod tests {
#[test] #[test]
fn test_history_handler_not_ready_when_history_is_empty() { fn test_history_handler_not_ready_when_history_is_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.is_loading = false; app.is_loading = false;
let handler = HistoryHandler::with( let handler = HistoryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
@@ -340,7 +357,7 @@ mod tests {
#[test] #[test]
fn test_history_handler_ready_when_not_loading_and_history_is_not_empty() { fn test_history_handler_ready_when_not_loading_and_history_is_not_empty() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::History.into()); app.push_navigation_stack(ActiveSonarrBlock::History.into());
app.is_loading = false; app.is_loading = false;
app app
@@ -349,7 +366,7 @@ mod tests {
.history .history
.set_items(vec![SonarrHistoryItem::default()]); .set_items(vec![SonarrHistoryItem::default()]);
let handler = HistoryHandler::with( let handler = HistoryHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::History, ActiveSonarrBlock::History,
+8 -5
View File
@@ -1,7 +1,5 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_table_events;
use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys; use crate::handlers::sonarr_handlers::handle_change_tab_left_right_keys;
use crate::handlers::table_handler::TableHandlingConfig; use crate::handlers::table_handler::TableHandlingConfig;
use crate::handlers::{handle_clear_errors, KeyEventHandler}; use crate::handlers::{handle_clear_errors, KeyEventHandler};
@@ -9,6 +7,7 @@ use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, HISTOR
use crate::models::servarr_models::Language; use crate::models::servarr_models::Language;
use crate::models::sonarr_models::SonarrHistoryItem; use crate::models::sonarr_models::SonarrHistoryItem;
use crate::models::stateful_table::SortOption; use crate::models::stateful_table::SortOption;
use crate::{handle_table_events, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "history_handler_tests.rs"] #[path = "history_handler_tests.rs"]
@@ -21,7 +20,7 @@ pub(super) struct HistoryHandler<'a, 'b> {
_context: Option<ActiveSonarrBlock>, _context: Option<ActiveSonarrBlock>,
} }
impl<'a, 'b> HistoryHandler<'a, 'b> { impl HistoryHandler<'_, '_> {
handle_table_events!( handle_table_events!(
self, self,
history, history,
@@ -52,7 +51,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for HistoryHandler<'a, '
HISTORY_BLOCKS.contains(&active_block) HISTORY_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveSonarrBlock, active_block: ActiveSonarrBlock,
@@ -110,7 +113,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for HistoryHandler<'a, '
let key = self.key; let key = self.key;
if self.active_sonarr_block == ActiveSonarrBlock::History { if self.active_sonarr_block == ActiveSonarrBlock::History {
match self.key { match self.key {
_ if key == DEFAULT_KEYBINDINGS.refresh.key => { _ if matches_key!(refresh, key) => {
self.app.should_refresh = true; self.app.should_refresh = true;
} }
_ => (), _ => (),
@@ -1,4 +1,3 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
@@ -6,7 +5,9 @@ use crate::models::servarr_data::modals::EditIndexerModal;
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS};
use crate::models::servarr_models::EditIndexerParams; use crate::models::servarr_models::EditIndexerParams;
use crate::network::sonarr_network::SonarrEvent; use crate::network::sonarr_network::SonarrEvent;
use crate::{handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys}; use crate::{
handle_prompt_left_right_keys, handle_text_box_keys, handle_text_box_left_right_keys, matches_key,
};
#[cfg(test)] #[cfg(test)]
#[path = "edit_indexer_handler_tests.rs"] #[path = "edit_indexer_handler_tests.rs"]
@@ -19,57 +20,43 @@ pub(super) struct EditIndexerHandler<'a, 'b> {
_context: Option<ActiveSonarrBlock>, _context: Option<ActiveSonarrBlock>,
} }
impl<'a, 'b> EditIndexerHandler<'a, 'b> { impl EditIndexerHandler<'_, '_> {
fn build_edit_indexer_params(&mut self) -> EditIndexerParams { fn build_edit_indexer_params(&mut self) -> EditIndexerParams {
let indexer_id = self.app.data.sonarr_data.indexers.current_selection().id; let edit_indexer_modal = self
let tags = self
.app .app
.data .data
.sonarr_data .sonarr_data
.edit_indexer_modal .edit_indexer_modal
.as_ref() .take()
.unwrap() .expect("EditIndexerModal is None");
.tags let indexer_id = self.app.data.sonarr_data.indexers.current_selection().id;
.text let tags = edit_indexer_modal.tags.text;
.clone(); let EditIndexerModal {
let params = { name,
let EditIndexerModal { enable_rss,
name, enable_automatic_search,
enable_rss, enable_interactive_search,
enable_automatic_search, url,
enable_interactive_search, api_key,
url, seed_ratio,
api_key, priority,
seed_ratio, ..
priority, } = edit_indexer_modal;
..
} = self
.app
.data
.sonarr_data
.edit_indexer_modal
.as_ref()
.unwrap();
EditIndexerParams { EditIndexerParams {
indexer_id, indexer_id,
name: Some(name.text.clone()), name: Some(name.text),
enable_rss: Some(enable_rss.unwrap_or_default()), enable_rss,
enable_automatic_search: Some(enable_automatic_search.unwrap_or_default()), enable_automatic_search,
enable_interactive_search: Some(enable_interactive_search.unwrap_or_default()), enable_interactive_search,
url: Some(url.text.clone()), url: Some(url.text),
api_key: Some(api_key.text.clone()), api_key: Some(api_key.text),
seed_ratio: Some(seed_ratio.text.clone()), seed_ratio: Some(seed_ratio.text),
tags: None, tags: None,
tag_input_string: Some(tags), tag_input_string: Some(tags),
priority: Some(*priority), priority: Some(priority),
clear_tags: false, clear_tags: false,
} }
};
self.app.data.sonarr_data.edit_indexer_modal = None;
params
} }
} }
@@ -78,7 +65,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditIndexerHandler<'
EDIT_INDEXER_BLOCKS.contains(&active_block) EDIT_INDEXER_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveSonarrBlock, active_block: ActiveSonarrBlock,
@@ -517,7 +508,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for EditIndexerHandler<'
ActiveSonarrBlock::EditIndexerPrompt => { ActiveSonarrBlock::EditIndexerPrompt => {
if self.app.data.sonarr_data.selected_block.get_active_block() if self.app.data.sonarr_data.selected_block.get_active_block()
== ActiveSonarrBlock::EditIndexerConfirmPrompt == ActiveSonarrBlock::EditIndexerConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = self.app.data.sonarr_data.prompt_confirm_action =
@@ -10,6 +10,7 @@ mod tests {
use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS}; use crate::models::servarr_data::sonarr::sonarr_data::{ActiveSonarrBlock, EDIT_INDEXER_BLOCKS};
use crate::models::servarr_models::EditIndexerParams; use crate::models::servarr_models::EditIndexerParams;
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
mod test_handle_scroll_up_and_down { mod test_handle_scroll_up_and_down {
@@ -25,11 +26,11 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_priority_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_priority_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPriorityInput, ActiveSonarrBlock::EditIndexerPriorityInput,
@@ -60,7 +61,7 @@ mod tests {
0 0
); );
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Up, Key::Up,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPriorityInput, ActiveSonarrBlock::EditIndexerPriorityInput,
@@ -79,7 +80,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPriorityInput, ActiveSonarrBlock::EditIndexerPriorityInput,
@@ -101,14 +102,14 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.down(); app.data.sonarr_data.selected_block.down();
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
if key == Key::Up { if key == Key::Up {
assert_eq!( assert_eq!(
@@ -127,7 +128,7 @@ mod tests {
fn test_edit_indexer_prompt_scroll_no_op_when_not_ready( fn test_edit_indexer_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
@@ -135,7 +136,7 @@ mod tests {
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.down(); app.data.sonarr_data.selected_block.down();
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
@@ -155,14 +156,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_home_end() { fn test_edit_indexer_name_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -183,7 +184,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -207,14 +208,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_home_end() { fn test_edit_indexer_url_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -235,7 +236,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -259,14 +260,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_home_end() { fn test_edit_indexer_api_key_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -287,7 +288,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -311,14 +312,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_home_end() { fn test_edit_indexer_seed_ratio_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -339,7 +340,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -363,14 +364,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_home_end() { fn test_edit_indexer_tags_input_home_end() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.home.key, DEFAULT_KEYBINDINGS.home.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -391,7 +392,7 @@ mod tests {
4 4
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.end.key, DEFAULT_KEYBINDINGS.end.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -430,17 +431,17 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.y = EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1; app.data.sonarr_data.selected_block.y = EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1;
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert!(!app.data.sonarr_data.prompt_confirm); assert!(!app.data.sonarr_data.prompt_confirm);
} }
@@ -472,7 +473,7 @@ mod tests {
#[case] left_block: ActiveSonarrBlock, #[case] left_block: ActiveSonarrBlock,
#[case] right_block: ActiveSonarrBlock, #[case] right_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
@@ -483,14 +484,14 @@ mod tests {
left_block left_block
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
right_block right_block
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
@@ -525,7 +526,7 @@ mod tests {
#[case] left_block: ActiveSonarrBlock, #[case] left_block: ActiveSonarrBlock,
#[case] right_block: ActiveSonarrBlock, #[case] right_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_NZB_SELECTION_BLOCKS);
@@ -536,14 +537,14 @@ mod tests {
left_block left_block
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
right_block right_block
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
@@ -555,7 +556,7 @@ mod tests {
fn test_left_right_block_toggle_torren_empty_row_to_prompt_confirm( fn test_left_right_block_toggle_torren_empty_row_to_prompt_confirm(
#[values(Key::Left, Key::Right)] key: Key, #[values(Key::Left, Key::Right)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
@@ -567,14 +568,14 @@ mod tests {
ActiveSonarrBlock::EditIndexerPriorityInput ActiveSonarrBlock::EditIndexerPriorityInput
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
ActiveSonarrBlock::EditIndexerConfirmPrompt ActiveSonarrBlock::EditIndexerConfirmPrompt
); );
EditIndexerHandler::with(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle(); EditIndexerHandler::new(key, &mut app, ActiveSonarrBlock::EditIndexerPrompt, None).handle();
assert_eq!( assert_eq!(
app.data.sonarr_data.selected_block.get_active_block(), app.data.sonarr_data.selected_block.get_active_block(),
@@ -585,14 +586,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_left_right_keys() { fn test_edit_indexer_name_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -613,7 +614,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -637,14 +638,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_left_right_keys() { fn test_edit_indexer_url_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -665,7 +666,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -689,14 +690,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_left_right_keys() { fn test_edit_indexer_api_key_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -717,7 +718,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -741,14 +742,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_left_right_keys() { fn test_edit_indexer_seed_ratio_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -769,7 +770,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -793,14 +794,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_left_right_keys() { fn test_edit_indexer_tags_input_left_right_keys() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.left.key, DEFAULT_KEYBINDINGS.left.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -821,7 +822,7 @@ mod tests {
1 1
); );
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.right.key, DEFAULT_KEYBINDINGS.right.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -861,7 +862,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_decline_submit() { fn test_edit_indexer_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -873,7 +874,7 @@ mod tests {
.set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1); .set_index(0, EDIT_INDEXER_TORRENT_SELECTION_BLOCKS.len() - 1);
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -889,7 +890,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_submit() { fn test_edit_indexer_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -927,7 +928,7 @@ mod tests {
}; };
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -946,14 +947,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_indexer_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -981,7 +982,7 @@ mod tests {
#[case] starting_x: usize, #[case] starting_x: usize,
#[case] block: ActiveSonarrBlock, #[case] block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
@@ -993,7 +994,7 @@ mod tests {
.selected_block .selected_block
.set_index(starting_x, starting_y); .set_index(starting_x, starting_y);
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1007,7 +1008,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_priority_input_submit() { fn test_edit_indexer_priority_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
@@ -1015,7 +1016,7 @@ mod tests {
BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS); BlockSelectionState::new(EDIT_INDEXER_TORRENT_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.set_index(0, 4); app.data.sonarr_data.selected_block.set_index(0, 4);
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1032,7 +1033,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_rss_submit() { fn test_edit_indexer_toggle_enable_rss_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -1040,7 +1041,7 @@ mod tests {
app.data.sonarr_data.selected_block.set_index(0, 1); app.data.sonarr_data.selected_block.set_index(0, 1);
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1061,7 +1062,7 @@ mod tests {
.enable_rss .enable_rss
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1085,7 +1086,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_automatic_search_submit() { fn test_edit_indexer_toggle_enable_automatic_search_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -1093,7 +1094,7 @@ mod tests {
app.data.sonarr_data.selected_block.set_index(0, 2); app.data.sonarr_data.selected_block.set_index(0, 2);
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1114,7 +1115,7 @@ mod tests {
.enable_automatic_search .enable_automatic_search
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1138,7 +1139,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_toggle_enable_interactive_search_submit() { fn test_edit_indexer_toggle_enable_interactive_search_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -1146,7 +1147,7 @@ mod tests {
app.data.sonarr_data.selected_block.set_index(0, 3); app.data.sonarr_data.selected_block.set_index(0, 3);
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1167,7 +1168,7 @@ mod tests {
.enable_interactive_search .enable_interactive_search
.unwrap()); .unwrap());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1191,7 +1192,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_submit() { fn test_edit_indexer_name_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1201,7 +1202,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerNameInput.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerNameInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -1227,7 +1228,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_submit() { fn test_edit_indexer_url_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1237,7 +1238,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerUrlInput.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerUrlInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -1263,7 +1264,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_submit() { fn test_edit_indexer_api_key_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1273,7 +1274,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerApiKeyInput.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerApiKeyInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -1299,7 +1300,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_submit() { fn test_edit_indexer_seed_ratio_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1309,7 +1310,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerSeedRatioInput.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerSeedRatioInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -1335,7 +1336,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_submit() { fn test_edit_indexer_tags_input_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
@@ -1345,7 +1346,7 @@ mod tests {
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerTagsInput.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerTagsInput.into());
EditIndexerHandler::with( EditIndexerHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -1382,13 +1383,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_prompt_esc(#[values(true, false)] is_ready: bool) { fn test_edit_indexer_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1413,13 +1414,13 @@ mod tests {
)] )]
active_sonarr_block: ActiveSonarrBlock, active_sonarr_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(active_sonarr_block.into()); app.push_navigation_stack(active_sonarr_block.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
app.should_ignore_quit_key = true; app.should_ignore_quit_key = true;
EditIndexerHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); EditIndexerHandler::new(ESC_KEY, &mut app, active_sonarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into());
assert!(!app.should_ignore_quit_key); assert!(!app.should_ignore_quit_key);
@@ -1442,14 +1443,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_backspace() { fn test_edit_indexer_name_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
name: "Test".into(), name: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
@@ -1472,14 +1473,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_url_input_backspace() { fn test_edit_indexer_url_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
url: "Test".into(), url: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
@@ -1502,14 +1503,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_api_key_input_backspace() { fn test_edit_indexer_api_key_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
api_key: "Test".into(), api_key: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
@@ -1532,14 +1533,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_backspace() { fn test_edit_indexer_seed_ratio_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
seed_ratio: "Test".into(), seed_ratio: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
@@ -1562,14 +1563,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_tags_input_backspace() { fn test_edit_indexer_tags_input_backspace() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal { app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal {
tags: "Test".into(), tags: "Test".into(),
..EditIndexerModal::default() ..EditIndexerModal::default()
}); });
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.backspace.key, DEFAULT_KEYBINDINGS.backspace.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
@@ -1592,12 +1593,12 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_name_input_char_key() { fn test_edit_indexer_name_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerNameInput, ActiveSonarrBlock::EditIndexerNameInput,
None, None,
@@ -1613,18 +1614,18 @@ mod tests {
.unwrap() .unwrap()
.name .name
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_url_input_char_key() { fn test_edit_indexer_url_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerUrlInput, ActiveSonarrBlock::EditIndexerUrlInput,
None, None,
@@ -1640,18 +1641,18 @@ mod tests {
.unwrap() .unwrap()
.url .url
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_api_key_input_char_key() { fn test_edit_indexer_api_key_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerApiKeyInput, ActiveSonarrBlock::EditIndexerApiKeyInput,
None, None,
@@ -1667,18 +1668,18 @@ mod tests {
.unwrap() .unwrap()
.api_key .api_key
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_seed_ratio_input_char_key() { fn test_edit_indexer_seed_ratio_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerSeedRatioInput, ActiveSonarrBlock::EditIndexerSeedRatioInput,
None, None,
@@ -1694,18 +1695,18 @@ mod tests {
.unwrap() .unwrap()
.seed_ratio .seed_ratio
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_tags_input_char_key() { fn test_edit_indexer_tags_input_char_key() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
EditIndexerHandler::with( EditIndexerHandler::new(
Key::Char('h'), Key::Char('a'),
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerTagsInput, ActiveSonarrBlock::EditIndexerTagsInput,
None, None,
@@ -1721,13 +1722,13 @@ mod tests {
.unwrap() .unwrap()
.tags .tags
.text, .text,
"h" "a"
); );
} }
#[test] #[test]
fn test_edit_indexer_prompt_prompt_confirmation_confirm() { fn test_edit_indexer_prompt_prompt_confirmation_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::EditIndexerPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -1764,7 +1765,7 @@ mod tests {
..EditIndexerParams::default() ..EditIndexerParams::default()
}; };
EditIndexerHandler::with( EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1793,9 +1794,25 @@ mod tests {
}) })
} }
#[rstest]
fn test_edit_indexer_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_indexer_params() { fn test_build_edit_indexer_params() {
let mut app = App::default(); let mut app = App::test_default();
let edit_indexer_modal = EditIndexerModal { let edit_indexer_modal = EditIndexerModal {
name: "Test Update".into(), name: "Test Update".into(),
enable_rss: Some(false), enable_rss: Some(false),
@@ -1823,7 +1840,7 @@ mod tests {
..EditIndexerParams::default() ..EditIndexerParams::default()
}; };
let params = EditIndexerHandler::with( let params = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1837,11 +1854,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_not_ready_when_loading() { fn test_edit_indexer_handler_is_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1853,11 +1870,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_not_ready_when_edit_indexer_modal_is_none() { fn test_edit_indexer_handler_is_not_ready_when_edit_indexer_modal_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1869,12 +1886,12 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_handler_is_ready_when_edit_indexer_modal_is_some() { fn test_edit_indexer_handler_is_ready_when_edit_indexer_modal_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default()); app.data.sonarr_data.edit_indexer_modal = Some(EditIndexerModal::default());
let handler = EditIndexerHandler::with( let handler = EditIndexerHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::EditIndexerPrompt, ActiveSonarrBlock::EditIndexerPrompt,
@@ -1,13 +1,12 @@
use crate::app::key_binding::DEFAULT_KEYBINDINGS;
use crate::app::App; use crate::app::App;
use crate::event::Key; use crate::event::Key;
use crate::handle_prompt_left_right_keys;
use crate::handlers::{handle_prompt_toggle, KeyEventHandler}; use crate::handlers::{handle_prompt_toggle, KeyEventHandler};
use crate::models::servarr_data::sonarr::sonarr_data::{ use crate::models::servarr_data::sonarr::sonarr_data::{
ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS, ActiveSonarrBlock, INDEXER_SETTINGS_BLOCKS,
}; };
use crate::models::sonarr_models::IndexerSettings; use crate::models::sonarr_models::IndexerSettings;
use crate::network::sonarr_network::SonarrEvent; use crate::network::sonarr_network::SonarrEvent;
use crate::{handle_prompt_left_right_keys, matches_key};
#[cfg(test)] #[cfg(test)]
#[path = "edit_indexer_settings_handler_tests.rs"] #[path = "edit_indexer_settings_handler_tests.rs"]
@@ -20,20 +19,15 @@ pub(super) struct IndexerSettingsHandler<'a, 'b> {
_context: Option<ActiveSonarrBlock>, _context: Option<ActiveSonarrBlock>,
} }
impl<'a, 'b> IndexerSettingsHandler<'a, 'b> { impl IndexerSettingsHandler<'_, '_> {
fn build_edit_indexer_settings_params(&mut self) -> IndexerSettings { fn build_edit_indexer_settings_params(&mut self) -> IndexerSettings {
let indexer_settings = self self
.app .app
.data .data
.sonarr_data .sonarr_data
.indexer_settings .indexer_settings
.as_ref() .take()
.unwrap() .expect("IndexerSettings is None")
.clone();
self.app.data.sonarr_data.indexer_settings = None;
indexer_settings
} }
} }
@@ -42,7 +36,11 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for IndexerSettingsHandl
INDEXER_SETTINGS_BLOCKS.contains(&active_block) INDEXER_SETTINGS_BLOCKS.contains(&active_block)
} }
fn with( fn ignore_alt_navigation(&self) -> bool {
self.app.should_ignore_quit_key
}
fn new(
key: Key, key: Key,
app: &'a mut App<'b>, app: &'a mut App<'b>,
active_block: ActiveSonarrBlock, active_block: ActiveSonarrBlock,
@@ -188,7 +186,7 @@ impl<'a, 'b> KeyEventHandler<'a, 'b, ActiveSonarrBlock> for IndexerSettingsHandl
if self.active_sonarr_block == ActiveSonarrBlock::AllIndexerSettingsPrompt if self.active_sonarr_block == ActiveSonarrBlock::AllIndexerSettingsPrompt
&& self.app.data.sonarr_data.selected_block.get_active_block() && self.app.data.sonarr_data.selected_block.get_active_block()
== ActiveSonarrBlock::IndexerSettingsConfirmPrompt == ActiveSonarrBlock::IndexerSettingsConfirmPrompt
&& self.key == DEFAULT_KEYBINDINGS.confirm.key && matches_key!(confirm, self.key)
{ {
self.app.data.sonarr_data.prompt_confirm = true; self.app.data.sonarr_data.prompt_confirm = true;
self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditAllIndexerSettings( self.app.data.sonarr_data.prompt_confirm_action = Some(SonarrEvent::EditAllIndexerSettings(
@@ -1,6 +1,7 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use pretty_assertions::assert_eq; use pretty_assertions::assert_eq;
use rstest::rstest;
use strum::IntoEnumIterator; use strum::IntoEnumIterator;
use crate::app::key_binding::DEFAULT_KEYBINDINGS; use crate::app::key_binding::DEFAULT_KEYBINDINGS;
@@ -26,11 +27,11 @@ mod tests {
macro_rules! test_i64_counter_scroll_value { macro_rules! test_i64_counter_scroll_value {
($block:expr, $key:expr, $data_ref:ident, $negatives:literal) => { ($block:expr, $key:expr, $data_ref:ident, $negatives:literal) => {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with($key, &mut app, $block, None).handle(); IndexerSettingsHandler::new($key, &mut app, $block, None).handle();
if $key == Key::Up { if $key == Key::Up {
assert_eq!( assert_eq!(
@@ -67,7 +68,7 @@ mod tests {
0 0
); );
IndexerSettingsHandler::with(Key::Up, &mut app, $block, None).handle(); IndexerSettingsHandler::new(Key::Up, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app app
@@ -80,7 +81,7 @@ mod tests {
1 1
); );
IndexerSettingsHandler::with($key, &mut app, $block, None).handle(); IndexerSettingsHandler::new($key, &mut app, $block, None).handle();
assert_eq!( assert_eq!(
app app
.data .data
@@ -98,14 +99,14 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_settings_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) { fn test_edit_indexer_settings_prompt_scroll(#[values(Key::Up, Key::Down)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.down(); app.data.sonarr_data.selected_block.down();
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -130,7 +131,7 @@ mod tests {
fn test_edit_indexer_settings_prompt_scroll_no_op_when_not_ready( fn test_edit_indexer_settings_prompt_scroll_no_op_when_not_ready(
#[values(Key::Up, Key::Down)] key: Key, #[values(Key::Up, Key::Down)] key: Key,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
@@ -138,7 +139,7 @@ mod tests {
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.down(); app.data.sonarr_data.selected_block.down();
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -203,13 +204,13 @@ mod tests {
#[rstest] #[rstest]
fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) { fn test_left_right_prompt_toggle(#[values(Key::Left, Key::Right)] key: Key) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.y = INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1; app.data.sonarr_data.selected_block.y = INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -219,7 +220,7 @@ mod tests {
assert!(app.data.sonarr_data.prompt_confirm); assert!(app.data.sonarr_data.prompt_confirm);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
key, key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -249,7 +250,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_decline_submit() { fn test_edit_indexer_settings_prompt_prompt_decline_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -261,7 +262,7 @@ mod tests {
.set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1); .set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1);
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -277,7 +278,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_submit() { fn test_edit_indexer_settings_prompt_prompt_confirmation_submit() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -290,7 +291,7 @@ mod tests {
app.data.sonarr_data.indexer_settings = Some(indexer_settings()); app.data.sonarr_data.indexer_settings = Some(indexer_settings());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -309,14 +310,14 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_submit_no_op_when_not_ready() { fn test_edit_indexer_settings_prompt_prompt_confirmation_submit_no_op_when_not_ready() {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = true; app.is_loading = true;
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
app.data.sonarr_data.prompt_confirm = true; app.data.sonarr_data.prompt_confirm = true;
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -340,7 +341,7 @@ mod tests {
#[case] selected_block: ActiveSonarrBlock, #[case] selected_block: ActiveSonarrBlock,
#[case] y_index: usize, #[case] y_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
@@ -348,7 +349,7 @@ mod tests {
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.set_index(0, y_index); app.data.sonarr_data.selected_block.set_index(0, y_index);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -363,7 +364,7 @@ mod tests {
fn test_edit_indexer_settings_prompt_submit_selected_block_no_op_when_not_ready( fn test_edit_indexer_settings_prompt_submit_selected_block_no_op_when_not_ready(
#[values(0, 1, 2, 3, 4)] y_index: usize, #[values(0, 1, 2, 3, 4)] y_index: usize,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
@@ -372,7 +373,7 @@ mod tests {
BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS); BlockSelectionState::new(INDEXER_SETTINGS_SELECTION_BLOCKS);
app.data.sonarr_data.selected_block.set_index(0, y_index); app.data.sonarr_data.selected_block.set_index(0, y_index);
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
SUBMIT_KEY, SUBMIT_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -396,13 +397,13 @@ mod tests {
)] )]
active_sonarr_block: ActiveSonarrBlock, active_sonarr_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.push_navigation_stack(active_sonarr_block.into()); app.push_navigation_stack(active_sonarr_block.into());
IndexerSettingsHandler::with(SUBMIT_KEY, &mut app, active_sonarr_block, None).handle(); IndexerSettingsHandler::new(SUBMIT_KEY, &mut app, active_sonarr_block, None).handle();
assert_eq!( assert_eq!(
app.get_current_route(), app.get_current_route(),
@@ -423,13 +424,13 @@ mod tests {
#[rstest] #[rstest]
fn test_edit_indexer_settings_prompt_esc(#[values(true, false)] is_ready: bool) { fn test_edit_indexer_settings_prompt_esc(#[values(true, false)] is_ready: bool) {
let mut app = App::default(); let mut app = App::test_default();
app.is_loading = is_ready; app.is_loading = is_ready;
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
ESC_KEY, ESC_KEY,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -452,12 +453,12 @@ mod tests {
)] )]
active_sonarr_block: ActiveSonarrBlock, active_sonarr_block: ActiveSonarrBlock,
) { ) {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(active_sonarr_block.into()); app.push_navigation_stack(active_sonarr_block.into());
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
IndexerSettingsHandler::with(ESC_KEY, &mut app, active_sonarr_block, None).handle(); IndexerSettingsHandler::new(ESC_KEY, &mut app, active_sonarr_block, None).handle();
assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into()); assert_eq!(app.get_current_route(), ActiveSonarrBlock::Indexers.into());
assert_eq!( assert_eq!(
@@ -480,7 +481,7 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_prompt_prompt_confirmation_confirm() { fn test_edit_indexer_settings_prompt_prompt_confirmation_confirm() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into()); app.push_navigation_stack(ActiveSonarrBlock::AllIndexerSettingsPrompt.into());
app.data.sonarr_data.selected_block = app.data.sonarr_data.selected_block =
@@ -492,7 +493,7 @@ mod tests {
.set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1); .set_index(0, INDEXER_SETTINGS_SELECTION_BLOCKS.len() - 1);
app.data.sonarr_data.indexer_settings = Some(indexer_settings()); app.data.sonarr_data.indexer_settings = Some(indexer_settings());
IndexerSettingsHandler::with( IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.confirm.key, DEFAULT_KEYBINDINGS.confirm.key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -521,12 +522,28 @@ mod tests {
}) })
} }
#[rstest]
fn test_indexer_settings_handler_ignore_alt_navigation(
#[values(true, false)] should_ignore_quit_key: bool,
) {
let mut app = App::test_default();
app.should_ignore_quit_key = should_ignore_quit_key;
let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key,
&mut app,
ActiveSonarrBlock::default(),
None,
);
assert_eq!(handler.ignore_alt_navigation(), should_ignore_quit_key);
}
#[test] #[test]
fn test_build_edit_indexer_settings_params() { fn test_build_edit_indexer_settings_params() {
let mut app = App::default(); let mut app = App::test_default();
app.data.sonarr_data.indexer_settings = Some(indexer_settings()); app.data.sonarr_data.indexer_settings = Some(indexer_settings());
let actual_indexer_settings = IndexerSettingsHandler::with( let actual_indexer_settings = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -540,11 +557,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_not_ready_when_loading() { fn test_edit_indexer_settings_handler_not_ready_when_loading() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = true; app.is_loading = true;
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -556,11 +573,11 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_not_ready_when_indexer_settings_is_none() { fn test_edit_indexer_settings_handler_not_ready_when_indexer_settings_is_none() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,
@@ -572,12 +589,12 @@ mod tests {
#[test] #[test]
fn test_edit_indexer_settings_handler_ready_when_not_loading_and_indexer_settings_is_some() { fn test_edit_indexer_settings_handler_ready_when_not_loading_and_indexer_settings_is_some() {
let mut app = App::default(); let mut app = App::test_default();
app.push_navigation_stack(ActiveSonarrBlock::Indexers.into()); app.push_navigation_stack(ActiveSonarrBlock::Indexers.into());
app.is_loading = false; app.is_loading = false;
app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default()); app.data.sonarr_data.indexer_settings = Some(IndexerSettings::default());
let handler = IndexerSettingsHandler::with( let handler = IndexerSettingsHandler::new(
DEFAULT_KEYBINDINGS.esc.key, DEFAULT_KEYBINDINGS.esc.key,
&mut app, &mut app,
ActiveSonarrBlock::AllIndexerSettingsPrompt, ActiveSonarrBlock::AllIndexerSettingsPrompt,

Some files were not shown because too many files have changed in this diff Show More