mirror of
https://github.com/Radarr/Radarr.git
synced 2026-03-17 16:14:46 -04:00
Compare commits
49 Commits
v4.1.0.609
...
remove-mon
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6683c88bb9 | ||
|
|
5824ba963b | ||
|
|
7f2d5d8d10 | ||
|
|
81bffe243a | ||
|
|
2d6fde282a | ||
|
|
3125b038d5 | ||
|
|
89e25a6241 | ||
|
|
4db6688fe0 | ||
|
|
4ac1aeaf06 | ||
|
|
e2ae743ee1 | ||
|
|
9ad316a6f5 | ||
|
|
b643d2e23d | ||
|
|
6a03eddda9 | ||
|
|
1576bf1f17 | ||
|
|
6325b70e27 | ||
|
|
24206ad0a3 | ||
|
|
2fc7cbff89 | ||
|
|
55ef505d74 | ||
|
|
cabdad6306 | ||
|
|
8d4b2dd21b | ||
|
|
ad04031c99 | ||
|
|
e9a5f87e45 | ||
|
|
bc6ac0cd4b | ||
|
|
c2328e4b79 | ||
|
|
36119facf0 | ||
|
|
a1fa1ddf5d | ||
|
|
ba770dce73 | ||
|
|
d58f0806f6 | ||
|
|
a95f8fa873 | ||
|
|
d1a9cf98cc | ||
|
|
be29fc6adb | ||
|
|
c1085e965b | ||
|
|
dc5c997e9b | ||
|
|
040acbf65a | ||
|
|
d089d036e6 | ||
|
|
46732c7d73 | ||
|
|
8fd3254745 | ||
|
|
9b21408a03 | ||
|
|
bd53092f0c | ||
|
|
80b1aa9a2c | ||
|
|
df863a08a1 | ||
|
|
8a0c318540 | ||
|
|
4f9d067361 | ||
|
|
6739310ba8 | ||
|
|
a45b91abe8 | ||
|
|
1ad2dc54b3 | ||
|
|
7f0b708cb9 | ||
|
|
c8cdf03077 | ||
|
|
c8afe578f3 |
@@ -19,10 +19,10 @@ indent_size = 4
|
||||
dotnet_sort_system_directives_first = true
|
||||
|
||||
# Avoid "this." and "Me." if not necessary
|
||||
dotnet_style_qualification_for_field = false:refactoring
|
||||
dotnet_style_qualification_for_property = false:refactoring
|
||||
dotnet_style_qualification_for_method = false:refactoring
|
||||
dotnet_style_qualification_for_event = false:refactoring
|
||||
dotnet_style_qualification_for_field = false:warning
|
||||
dotnet_style_qualification_for_property = false:warning
|
||||
dotnet_style_qualification_for_method = false:warning
|
||||
dotnet_style_qualification_for_event = false:warning
|
||||
|
||||
# Indentation preferences
|
||||
csharp_indent_block_contents = true
|
||||
@@ -32,10 +32,6 @@ csharp_indent_case_contents_when_block = true
|
||||
csharp_indent_switch_labels = true
|
||||
csharp_indent_labels = flush_left
|
||||
|
||||
dotnet_style_qualification_for_field = false:suggestion
|
||||
dotnet_style_qualification_for_property = false:suggestion
|
||||
dotnet_style_qualification_for_method = false:suggestion
|
||||
dotnet_style_qualification_for_event = false:suggestion
|
||||
dotnet_naming_style.instance_field_style.capitalization = camel_case
|
||||
dotnet_naming_style.instance_field_style.required_prefix = _
|
||||
|
||||
|
||||
@@ -7,16 +7,20 @@ variables:
|
||||
outputFolder: './_output'
|
||||
artifactsFolder: './_artifacts'
|
||||
testsFolder: './_tests'
|
||||
majorVersion: '4.1.0'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
|
||||
majorVersion: '4.2.0'
|
||||
minorVersion: $[counter('minorVersion', 2000)]
|
||||
radarrVersion: '$(majorVersion).$(minorVersion)'
|
||||
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
|
||||
sentryOrg: 'servarr'
|
||||
sentryUrl: 'https://sentry.servarr.com'
|
||||
dotnetVersion: '6.0.201'
|
||||
dotnetVersion: '6.0.202'
|
||||
nodeVersion: '16.X'
|
||||
innoVersion: '6.2.0'
|
||||
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
|
||||
windowsImage: 'windows-2022'
|
||||
linuxImage: 'ubuntu-20.04'
|
||||
macImage: 'macOS-11'
|
||||
|
||||
trigger:
|
||||
branches:
|
||||
@@ -40,7 +44,7 @@ stages:
|
||||
- job:
|
||||
displayName: Build Variables
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
# Set the build name properly. The 'name' property won't recursively expand so hack here:
|
||||
- bash: echo "##vso[build.updatebuildnumber]$RADARRVERSION"
|
||||
@@ -66,15 +70,15 @@ stages:
|
||||
matrix:
|
||||
Linux:
|
||||
osName: 'Linux'
|
||||
imageName: 'ubuntu-18.04'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
enableAnalysis: 'true'
|
||||
Mac:
|
||||
osName: 'Mac'
|
||||
imageName: 'macos-10.15'
|
||||
imageName: ${{ variables.macImage }}
|
||||
enableAnalysis: 'false'
|
||||
Windows:
|
||||
osName: 'Windows'
|
||||
imageName: 'windows-2019'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
enableAnalysis: 'false'
|
||||
|
||||
pool:
|
||||
@@ -93,15 +97,14 @@ stages:
|
||||
- bash: |
|
||||
BUNDLEDVERSIONS=${AGENT_TOOLSDIRECTORY}/dotnet/sdk/${DOTNETVERSION}/Microsoft.NETCoreSdk.BundledVersions.props
|
||||
echo $BUNDLEDVERSIONS
|
||||
grep osx-x64 $BUNDLEDVERSIONS
|
||||
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
|
||||
echo "BSD already enabled"
|
||||
echo "Extra platforms already enabled"
|
||||
else
|
||||
echo "Enabling BSD support"
|
||||
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64/' $BUNDLEDVERSIONS
|
||||
echo "Enabling extra platform support"
|
||||
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
|
||||
fi
|
||||
displayName: Enable FreeBSD Support
|
||||
- bash: ./build.sh --backend --enable-bsd
|
||||
displayName: Enable Extra Platform Support
|
||||
- bash: ./build.sh --backend --enable-extra-platforms
|
||||
displayName: Build Radarr Backend
|
||||
- bash: |
|
||||
find ${OUTPUTFOLDER} -type f ! -path "*/publish/*" -exec rm -rf {} \;
|
||||
@@ -115,24 +118,28 @@ stages:
|
||||
displayName: Publish Backend
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/win-x64/publish'
|
||||
artifact: WindowsCoreTests
|
||||
displayName: Publish Windows Test Package
|
||||
artifact: win-x64-tests
|
||||
displayName: Publish win-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-x64/publish'
|
||||
artifact: LinuxCoreTests
|
||||
displayName: Publish Linux Test Package
|
||||
artifact: linux-x64-tests
|
||||
displayName: Publish linux-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-x86/publish'
|
||||
artifact: linux-x86-tests
|
||||
displayName: Publish linux-x86 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/linux-musl-x64/publish'
|
||||
artifact: LinuxMuslCoreTests
|
||||
displayName: Publish Linux Musl Test Package
|
||||
artifact: linux-musl-x64-tests
|
||||
displayName: Publish linux-musl-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/freebsd-x64/publish'
|
||||
artifact: FreebsdCoreTests
|
||||
displayName: Publish FreeBSD Test Package
|
||||
artifact: freebsd-x64-tests
|
||||
displayName: Publish freebsd-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
- publish: '$(testsFolder)/net6.0/osx-x64/publish'
|
||||
artifact: MacCoreTests
|
||||
displayName: Publish MacOS Test Package
|
||||
artifact: osx-x64-tests
|
||||
displayName: Publish osx-x64 Test Package
|
||||
condition: and(succeeded(), eq(variables['osName'], 'Windows'))
|
||||
|
||||
- stage: Build_Frontend
|
||||
@@ -144,13 +151,13 @@ stages:
|
||||
matrix:
|
||||
Linux:
|
||||
osName: 'Linux'
|
||||
imageName: 'ubuntu-18.04'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
Mac:
|
||||
osName: 'Mac'
|
||||
imageName: 'macos-10.15'
|
||||
imageName: ${{ variables.macImage }}
|
||||
Windows:
|
||||
osName: 'Windows'
|
||||
imageName: 'windows-2019'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
@@ -187,7 +194,7 @@ stages:
|
||||
- job: Windows_Installer
|
||||
displayName: Create Installer
|
||||
pool:
|
||||
vmImage: 'windows-2019'
|
||||
vmImage: ${{ variables.windowsImage }}
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
@@ -220,7 +227,7 @@ stages:
|
||||
- job: Other_Packages
|
||||
displayName: Create Standard Packages
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
- checkout: self
|
||||
fetchDepth: 1
|
||||
@@ -236,7 +243,7 @@ stages:
|
||||
artifactName: WindowsFrontend
|
||||
targetPath: _output
|
||||
displayName: Fetch Frontend
|
||||
- bash: ./build.sh --packages --enable-bsd
|
||||
- bash: ./build.sh --packages --enable-extra-platforms
|
||||
displayName: Create Packages
|
||||
- bash: |
|
||||
find . -name "ffprobe" -exec chmod a+x {} \;
|
||||
@@ -244,28 +251,28 @@ stages:
|
||||
find . -name "Radarr.Update" -exec chmod a+x {} \;
|
||||
displayName: Set executable bits
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Windows Core zip
|
||||
displayName: Create win-x64 zip
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/win-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Windows x86 Core zip
|
||||
displayName: Create win-x86 zip
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).windows-core-x86.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/win-x86/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS x64 Core app
|
||||
displayName: Create osx-x64 app
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-x64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-x64-app/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS x64 Core tar
|
||||
displayName: Create osx-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -273,14 +280,14 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS arm64 Core app
|
||||
displayName: Create osx-arm64 app
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-app-core-arm64.zip'
|
||||
archiveType: 'zip'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-arm64-app/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create MacOS arm64 Core tar
|
||||
displayName: Create osx-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).osx-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -288,7 +295,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/osx-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Core tar
|
||||
displayName: Create linux-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -296,7 +303,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create Linux Musl Core tar
|
||||
displayName: Create linux-musl-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -304,7 +311,15 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-x64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM32 Linux Core tar
|
||||
displayName: Create linux-x86 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-x86.tar.gz'
|
||||
archiveType: 'tar'
|
||||
tarCompression: 'gz'
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-x86/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create linux-arm tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -312,7 +327,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-arm/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM32 Linux Musl Core tar
|
||||
displayName: Create linux-musl-arm tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -320,7 +335,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM64 Linux Core tar
|
||||
displayName: Create linux-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -328,7 +343,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create ARM64 Linux Musl Core tar
|
||||
displayName: Create linux-musl-arm64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).linux-musl-core-arm64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -336,7 +351,7 @@ stages:
|
||||
includeRootFolder: false
|
||||
rootFolderOrFile: $(artifactsFolder)/linux-musl-arm64/net6.0
|
||||
- task: ArchiveFiles@2
|
||||
displayName: Create FreeBSD Core Core tar
|
||||
displayName: Create freebsd-x64 tar
|
||||
inputs:
|
||||
archiveFile: '$(Build.ArtifactStagingDirectory)/Radarr.$(buildName).freebsd-core-x64.tar.gz'
|
||||
archiveType: 'tar'
|
||||
@@ -381,7 +396,7 @@ stages:
|
||||
jobs:
|
||||
- job: Prepare
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
@@ -403,22 +418,22 @@ stages:
|
||||
matrix:
|
||||
MacCore:
|
||||
osName: 'Mac'
|
||||
testName: 'MacCore'
|
||||
testName: 'osx-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: 'macos-10.15'
|
||||
imageName: ${{ variables.macImage }}
|
||||
WindowsCore:
|
||||
osName: 'Windows'
|
||||
testName: 'WindowsCore'
|
||||
testName: 'win-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: 'windows-2019'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
LinuxCore:
|
||||
osName: 'Linux'
|
||||
testName: 'LinuxCore'
|
||||
testName: 'linux-x64'
|
||||
poolName: 'Azure Pipelines'
|
||||
imageName: 'ubuntu-18.04'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
FreebsdCore:
|
||||
osName: 'Linux'
|
||||
testName: 'FreebsdCore'
|
||||
testName: 'freebsd-x64'
|
||||
poolName: 'FreeBSD'
|
||||
imageName:
|
||||
|
||||
@@ -437,7 +452,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(testName)Tests'
|
||||
artifactName: '$(testName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- powershell: Set-Service SCardSvr -StartupType Manual
|
||||
displayName: Enable Windows Test Service
|
||||
@@ -471,11 +486,15 @@ stages:
|
||||
matrix:
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
artifactName: linux-musl-x64-tests
|
||||
containerImage: ghcr.io/servarr/testimages:alpine
|
||||
linux-x86:
|
||||
testName: 'linux-x86'
|
||||
artifactName: linux-x86-tests
|
||||
containerImage: ghcr.io/servarr/testimages:linux-x86
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
|
||||
container: $[ variables['containerImage'] ]
|
||||
|
||||
@@ -483,9 +502,15 @@ stages:
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
displayName: 'Install .NET'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
|
||||
- bash: |
|
||||
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
|
||||
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
|
||||
displayName: 'Install .NET'
|
||||
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
@@ -511,6 +536,61 @@ stages:
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: '$(testName) Unit Tests'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- job: Unit_LinuxCore_Postgres
|
||||
displayName: Unit Native LinuxCore with Postgres Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
artifactName: linux-x64-tests
|
||||
Radarr__Postgres__Host: 'localhost'
|
||||
Radarr__Postgres__Port: '5432'
|
||||
Radarr__Postgres__User: 'radarr'
|
||||
Radarr__Postgres__Password: 'radarr'
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
|
||||
timeoutInMinutes: 10
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: $(artifactName)
|
||||
targetPath: $(testsFolder)
|
||||
- bash: |
|
||||
chmod a+x _tests/ffprobe
|
||||
displayName: Make ffprobe Executable
|
||||
- bash: find ${TESTSFOLDER} -name "Radarr.Test.Dummy" -exec chmod a+x {} \;
|
||||
displayName: Make Test Dummy Executable
|
||||
condition: and(succeeded(), ne(variables['osName'], 'Windows'))
|
||||
- bash: |
|
||||
docker run -d --name=postgres14 \
|
||||
-e POSTGRES_PASSWORD=radarr \
|
||||
-e POSTGRES_USER=radarr \
|
||||
-p 5432:5432/tcp \
|
||||
postgres:14
|
||||
displayName: Start postgres
|
||||
- bash: |
|
||||
chmod a+x ${TESTSFOLDER}/test.sh
|
||||
ls -lR ${TESTSFOLDER}
|
||||
${TESTSFOLDER}/test.sh Linux Unit Test
|
||||
displayName: Run Tests
|
||||
- task: PublishTestResults@2
|
||||
displayName: Publish Test Results
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'LinuxCore Postgres Unit Tests'
|
||||
failTaskOnFailedTests: true
|
||||
|
||||
- stage: Integration
|
||||
displayName: Integration
|
||||
@@ -519,7 +599,7 @@ stages:
|
||||
jobs:
|
||||
- job: Prepare
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
@@ -538,18 +618,18 @@ stages:
|
||||
matrix:
|
||||
MacCore:
|
||||
osName: 'Mac'
|
||||
testName: 'MacCore'
|
||||
imageName: 'macos-10.15'
|
||||
testName: 'osx-x64'
|
||||
imageName: ${{ variables.macImage }}
|
||||
pattern: 'Radarr.*.osx-core-x64.tar.gz'
|
||||
WindowsCore:
|
||||
osName: 'Windows'
|
||||
testName: 'WindowsCore'
|
||||
imageName: 'windows-2019'
|
||||
testName: 'win-x64'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pattern: 'Radarr.*.windows-core-x64.zip'
|
||||
LinuxCore:
|
||||
osName: 'Linux'
|
||||
testName: 'LinuxCore'
|
||||
imageName: 'ubuntu-18.04'
|
||||
testName: 'linux-x64'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
|
||||
pool:
|
||||
@@ -565,7 +645,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(testName)Tests'
|
||||
artifactName: '$(testName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -595,6 +675,67 @@ stages:
|
||||
failTaskOnFailedTests: true
|
||||
displayName: Publish Test Results
|
||||
|
||||
- job: Integration_LinuxCore_Postgres
|
||||
displayName: Integration Native LinuxCore with Postgres Database
|
||||
dependsOn: Prepare
|
||||
condition: and(succeeded(), eq(dependencies.Prepare.outputs['setVar.backendNotUpdated'], '0'))
|
||||
variables:
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
Radarr__Postgres__Host: 'localhost'
|
||||
Radarr__Postgres__Port: '5432'
|
||||
Radarr__Postgres__User: 'radarr'
|
||||
Radarr__Postgres__Password: 'radarr'
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'linux-x64-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: Packages
|
||||
itemPattern: '**/$(pattern)'
|
||||
targetPath: $(Build.ArtifactStagingDirectory)
|
||||
- task: ExtractFiles@1
|
||||
inputs:
|
||||
archiveFilePatterns: '$(Build.ArtifactStagingDirectory)/**/$(pattern)'
|
||||
destinationFolder: '$(Build.ArtifactStagingDirectory)/bin'
|
||||
displayName: Extract Package
|
||||
- bash: |
|
||||
mkdir -p ./bin/
|
||||
cp -r -v ${BUILD_ARTIFACTSTAGINGDIRECTORY}/bin/Radarr/. ./bin/
|
||||
displayName: Move Package Contents
|
||||
- bash: |
|
||||
docker run -d --name=postgres14 \
|
||||
-e POSTGRES_PASSWORD=radarr \
|
||||
-e POSTGRES_USER=radarr \
|
||||
-p 5432:5432/tcp \
|
||||
postgres:14
|
||||
displayName: Start postgres
|
||||
- bash: |
|
||||
chmod a+x ${TESTSFOLDER}/test.sh
|
||||
${TESTSFOLDER}/test.sh Linux Integration Test
|
||||
displayName: Run Integration Tests
|
||||
- task: PublishTestResults@2
|
||||
inputs:
|
||||
testResultsFormat: 'NUnit'
|
||||
testResultsFiles: '**/TestResult.xml'
|
||||
testRunTitle: 'Integration LinuxCore Postgres Database Integration Tests'
|
||||
failTaskOnFailedTests: true
|
||||
displayName: Publish Test Results
|
||||
|
||||
- job: Integration_FreeBSD
|
||||
displayName: Integration Native FreeBSD
|
||||
dependsOn: Prepare
|
||||
@@ -612,7 +753,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: 'FreebsdCoreTests'
|
||||
artifactName: 'freebsd-x64-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -648,12 +789,17 @@ stages:
|
||||
strategy:
|
||||
matrix:
|
||||
alpine:
|
||||
testName: 'Musl Net Core'
|
||||
artifactName: LinuxMuslCoreTests
|
||||
testName: 'linux-musl-x64'
|
||||
artifactName: linux-musl-x64-tests
|
||||
containerImage: ghcr.io/servarr/testimages:alpine
|
||||
pattern: 'Radarr.*.linux-musl-core-x64.tar.gz'
|
||||
linux-x86:
|
||||
testName: 'linux-x86'
|
||||
artifactName: linux-x86-tests
|
||||
containerImage: ghcr.io/servarr/testimages:linux-x86
|
||||
pattern: 'Radarr.*.linux-core-x86.tar.gz'
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
|
||||
container: $[ variables['containerImage'] ]
|
||||
|
||||
@@ -661,9 +807,15 @@ stages:
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
displayName: 'Install .net core'
|
||||
displayName: 'Install .NET'
|
||||
inputs:
|
||||
version: $(dotnetVersion)
|
||||
condition: and(succeeded(), ne(variables['testName'], 'linux-x86'))
|
||||
- bash: |
|
||||
SDKURL=$(curl -s https://api.github.com/repos/Servarr/dotnet-linux-x86/releases | jq -rc '.[].assets[].browser_download_url' | grep sdk-${DOTNETVERSION}.*gz$)
|
||||
curl -fsSL $SDKURL | tar xzf - -C /opt/dotnet
|
||||
displayName: 'Install .NET'
|
||||
condition: and(succeeded(), eq(variables['testName'], 'linux-x86'))
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Test Artifact
|
||||
@@ -709,17 +861,20 @@ stages:
|
||||
matrix:
|
||||
Linux:
|
||||
osName: 'Linux'
|
||||
imageName: 'ubuntu-18.04'
|
||||
artifactName: 'linux-x64'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
pattern: 'Radarr.*.linux-core-x64.tar.gz'
|
||||
failBuild: true
|
||||
Mac:
|
||||
osName: 'Mac'
|
||||
imageName: 'macos-10.15'
|
||||
artifactName: 'osx-x64'
|
||||
imageName: ${{ variables.macImage }}
|
||||
pattern: 'Radarr.*.osx-core-x64.tar.gz'
|
||||
failBuild: true
|
||||
Windows:
|
||||
osName: 'Windows'
|
||||
imageName: 'windows-2019'
|
||||
artifactName: 'win-x64'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pattern: 'Radarr.*.windows-core-x64.zip'
|
||||
failBuild: true
|
||||
|
||||
@@ -736,7 +891,7 @@ stages:
|
||||
displayName: Download Test Artifact
|
||||
inputs:
|
||||
buildType: 'current'
|
||||
artifactName: '$(osName)CoreTests'
|
||||
artifactName: '$(artifactName)-tests'
|
||||
targetPath: $(testsFolder)
|
||||
- task: DownloadPipelineArtifact@2
|
||||
displayName: Download Build Artifact
|
||||
@@ -785,7 +940,7 @@ stages:
|
||||
jobs:
|
||||
- job: Prepare
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
- checkout: none
|
||||
- task: DownloadPipelineArtifact@2
|
||||
@@ -802,10 +957,10 @@ stages:
|
||||
matrix:
|
||||
Linux:
|
||||
osName: 'Linux'
|
||||
imageName: 'ubuntu-18.04'
|
||||
imageName: ${{ variables.linuxImage }}
|
||||
Windows:
|
||||
osName: 'Windows'
|
||||
imageName: 'windows-2019'
|
||||
imageName: ${{ variables.windowsImage }}
|
||||
pool:
|
||||
vmImage: $(imageName)
|
||||
steps:
|
||||
@@ -834,7 +989,7 @@ stages:
|
||||
displayName: Frontend
|
||||
condition: eq(variables['System.PullRequest.IsFork'], 'False')
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
vmImage: ${{ variables.windowsImage }}
|
||||
steps:
|
||||
- checkout: self # Need history for Sonar analysis
|
||||
- task: SonarCloudPrepare@1
|
||||
@@ -862,7 +1017,7 @@ stages:
|
||||
)
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
vmImage: ${{ variables.windowsImage }}
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
@@ -915,7 +1070,7 @@ stages:
|
||||
EnableAnalyzers: 'false'
|
||||
|
||||
pool:
|
||||
vmImage: windows-2019
|
||||
vmImage: ${{ variables.windowsImage }}
|
||||
|
||||
steps:
|
||||
- task: UseDotNet@2
|
||||
@@ -972,7 +1127,7 @@ stages:
|
||||
- job:
|
||||
displayName: Discord Notification
|
||||
pool:
|
||||
vmImage: 'ubuntu-18.04'
|
||||
vmImage: ${{ variables.linuxImage }}
|
||||
steps:
|
||||
- task: DownloadPipelineArtifact@2
|
||||
continueOnError: true
|
||||
|
||||
44
build.sh
44
build.sh
@@ -25,14 +25,22 @@ UpdateVersionNumber()
|
||||
fi
|
||||
}
|
||||
|
||||
EnableBsdSupport()
|
||||
EnableExtraPlatformsInSDK()
|
||||
{
|
||||
#todo enable sdk with
|
||||
#SDK_PATH=$(dotnet --list-sdks | grep -P '5\.\d\.\d+' | head -1 | sed 's/\(5\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g')
|
||||
# BUNDLED_VERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props"
|
||||
SDK_PATH=$(dotnet --list-sdks | grep -P '6\.\d\.\d+' | head -1 | sed 's/\(6\.[0-9]*\.[0-9]*\).*\[\(.*\)\]/\2\/\1/g')
|
||||
BUNDLEDVERSIONS="${SDK_PATH}/Microsoft.NETCoreSdk.BundledVersions.props"
|
||||
if grep -q freebsd-x64 $BUNDLEDVERSIONS; then
|
||||
echo "Extra platforms already enabled"
|
||||
else
|
||||
echo "Enabling extra platform support"
|
||||
sed -i.ORI 's/osx-x64/osx-x64;freebsd-x64;linux-x86/' $BUNDLEDVERSIONS
|
||||
fi
|
||||
}
|
||||
|
||||
EnableExtraPlatforms()
|
||||
{
|
||||
if grep -qv freebsd-x64 src/Directory.Build.props; then
|
||||
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64</RuntimeIdentifiers>^g" src/Directory.Build.props
|
||||
sed -i'' -e "s^<RuntimeIdentifiers>\(.*\)</RuntimeIdentifiers>^<RuntimeIdentifiers>\1;freebsd-x64;linux-x86</RuntimeIdentifiers>^g" src/Directory.Build.props
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -292,7 +300,8 @@ if [ $# -eq 0 ]; then
|
||||
PACKAGES=YES
|
||||
INSTALLER=NO
|
||||
LINT=YES
|
||||
ENABLE_BSD=NO
|
||||
ENABLE_EXTRA_PLATFORMS=NO
|
||||
ENABLE_EXTRA_PLATFORMS_IN_SDK=NO
|
||||
fi
|
||||
|
||||
while [[ $# -gt 0 ]]
|
||||
@@ -304,8 +313,12 @@ case $key in
|
||||
BACKEND=YES
|
||||
shift # past argument
|
||||
;;
|
||||
--enable-bsd)
|
||||
ENABLE_BSD=YES
|
||||
--enable-bsd|--enable-extra-platforms)
|
||||
ENABLE_EXTRA_PLATFORMS=YES
|
||||
shift # past argument
|
||||
;;
|
||||
--enable-extra-platforms-in-sdk)
|
||||
ENABLE_EXTRA_PLATFORMS_IN_SDK=YES
|
||||
shift # past argument
|
||||
;;
|
||||
-r|--runtime)
|
||||
@@ -349,12 +362,17 @@ esac
|
||||
done
|
||||
set -- "${POSITIONAL[@]}" # restore positional parameters
|
||||
|
||||
if [ "$ENABLE_EXTRA_PLATFORMS_IN_SDK" = "YES" ];
|
||||
then
|
||||
EnableExtraPlatformsInSDK
|
||||
fi
|
||||
|
||||
if [ "$BACKEND" = "YES" ];
|
||||
then
|
||||
UpdateVersionNumber
|
||||
if [ "$ENABLE_BSD" = "YES" ];
|
||||
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
|
||||
then
|
||||
EnableBsdSupport
|
||||
EnableExtraPlatforms
|
||||
fi
|
||||
Build
|
||||
if [[ -z "$RID" || -z "$FRAMEWORK" ]];
|
||||
@@ -364,9 +382,10 @@ then
|
||||
PackageTests "net6.0" "linux-x64"
|
||||
PackageTests "net6.0" "linux-musl-x64"
|
||||
PackageTests "net6.0" "osx-x64"
|
||||
if [ "$ENABLE_BSD" = "YES" ];
|
||||
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
|
||||
then
|
||||
PackageTests "net6.0" "freebsd-x64"
|
||||
PackageTests "net6.0" "linux-x86"
|
||||
fi
|
||||
else
|
||||
PackageTests "$FRAMEWORK" "$RID"
|
||||
@@ -405,9 +424,10 @@ then
|
||||
Package "net6.0" "linux-musl-arm"
|
||||
Package "net6.0" "osx-x64"
|
||||
Package "net6.0" "osx-arm64"
|
||||
if [ "$ENABLE_BSD" = "YES" ];
|
||||
if [ "$ENABLE_EXTRA_PLATFORMS" = "YES" ];
|
||||
then
|
||||
Package "net6.0" "freebsd-x64"
|
||||
Package "net6.0" "linux-x86"
|
||||
fi
|
||||
else
|
||||
Package "$FRAMEWORK" "$RID"
|
||||
|
||||
@@ -161,6 +161,7 @@ class DateFilterBuilderRowValue extends Component {
|
||||
<TextInput
|
||||
name={NAME}
|
||||
value={filterValue}
|
||||
type="date"
|
||||
placeholder="yyyy-mm-dd"
|
||||
onChange={this.onValueChange}
|
||||
/>
|
||||
|
||||
@@ -12,9 +12,9 @@ import ModalBody from 'Components/Modal/ModalBody';
|
||||
import Portal from 'Components/Portal';
|
||||
import Scroller from 'Components/Scroller/Scroller';
|
||||
import { icons, scrollDirections, sizes } from 'Helpers/Props';
|
||||
import { isMobile as isMobileUtil } from 'Utilities/browser';
|
||||
import * as keyCodes from 'Utilities/Constants/keyCodes';
|
||||
import getUniqueElememtId from 'Utilities/getUniqueElementId';
|
||||
import { isMobile as isMobileUtil } from 'Utilities/mobile';
|
||||
import HintedSelectInputOption from './HintedSelectInputOption';
|
||||
import HintedSelectInputSelectedValue from './HintedSelectInputSelectedValue';
|
||||
import TextInput from './TextInput';
|
||||
|
||||
@@ -6,9 +6,9 @@ import ReactDOM from 'react-dom';
|
||||
import FocusLock from 'react-focus-lock';
|
||||
import ErrorBoundary from 'Components/Error/ErrorBoundary';
|
||||
import { sizes } from 'Helpers/Props';
|
||||
import { isIOS } from 'Utilities/browser';
|
||||
import * as keyCodes from 'Utilities/Constants/keyCodes';
|
||||
import getUniqueElememtId from 'Utilities/getUniqueElementId';
|
||||
import { isIOS } from 'Utilities/mobile';
|
||||
import { setScrollLock } from 'Utilities/scrollLock';
|
||||
import ModalError from './ModalError';
|
||||
import styles from './Modal.css';
|
||||
|
||||
@@ -3,7 +3,7 @@ import React, { Component } from 'react';
|
||||
import OverlayScroller from 'Components/Scroller/OverlayScroller';
|
||||
import Scroller from 'Components/Scroller/Scroller';
|
||||
import { scrollDirections } from 'Helpers/Props';
|
||||
import { isMobile as isMobileUtil } from 'Utilities/mobile';
|
||||
import { isFirefox, isMobile } from 'Utilities/browser';
|
||||
import { isLocked } from 'Utilities/scrollLock';
|
||||
import styles from './PageContentBody.css';
|
||||
|
||||
@@ -15,7 +15,8 @@ class PageContentBody extends Component {
|
||||
constructor(props, context) {
|
||||
super(props, context);
|
||||
|
||||
this._isMobile = isMobileUtil();
|
||||
this._isMobile = isMobile();
|
||||
this._isSmallScreenFirefox = isFirefox && window.innerWidth < 768;
|
||||
}
|
||||
|
||||
//
|
||||
@@ -41,7 +42,9 @@ class PageContentBody extends Component {
|
||||
...otherProps
|
||||
} = this.props;
|
||||
|
||||
const ScrollerComponent = this._isMobile ? Scroller : OverlayScroller;
|
||||
const ScrollerComponent = this._isMobile || this._isSmallScreenFirefox ?
|
||||
Scroller :
|
||||
OverlayScroller;
|
||||
|
||||
return (
|
||||
<ScrollerComponent
|
||||
|
||||
@@ -5,7 +5,7 @@ import { Manager, Popper, Reference } from 'react-popper';
|
||||
import Portal from 'Components/Portal';
|
||||
import { kinds, tooltipPositions } from 'Helpers/Props';
|
||||
import dimensions from 'Styles/Variables/dimensions';
|
||||
import { isMobile as isMobileUtil } from 'Utilities/mobile';
|
||||
import { isMobile as isMobileUtil } from 'Utilities/browser';
|
||||
import styles from './Tooltip.css';
|
||||
|
||||
let maxWidth = null;
|
||||
|
||||
@@ -7,3 +7,9 @@
|
||||
.filteredMessage {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.blankpad {
|
||||
padding-top: 10px;
|
||||
padding-bottom: 10px;
|
||||
padding-left: 2em;
|
||||
}
|
||||
|
||||
@@ -127,21 +127,21 @@ function InteractiveSearchContent(props) {
|
||||
|
||||
{
|
||||
!isFetching && !!error &&
|
||||
<div>
|
||||
<div className={styles.blankpad}>
|
||||
{translate('UnableToLoadResultsIntSearch')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!isFetching && isPopulated && !totalReleasesCount &&
|
||||
<div>
|
||||
<div className={styles.blankpad}>
|
||||
{translate('NoResultsFound')}
|
||||
</div>
|
||||
}
|
||||
|
||||
{
|
||||
!!totalReleasesCount && isPopulated && !items.length &&
|
||||
<div>
|
||||
<div className={styles.blankpad}>
|
||||
{translate('AllResultsHiddenFilter')}
|
||||
</div>
|
||||
}
|
||||
@@ -159,7 +159,7 @@ function InteractiveSearchContent(props) {
|
||||
items.map((item) => {
|
||||
return (
|
||||
<InteractiveSearchRowConnector
|
||||
key={item.guid}
|
||||
key={`${item.indexerId}-${item.guid}`}
|
||||
{...item}
|
||||
searchPayload={searchPayload}
|
||||
longDateFormat={longDateFormat}
|
||||
|
||||
@@ -116,10 +116,11 @@ class NamingModal extends Component {
|
||||
|
||||
const movieTokens = [
|
||||
{ token: '{Movie Title}', example: 'Movie\'s Title' },
|
||||
{ token: '{Movie Title:DE}', example: 'Filetitle' },
|
||||
{ token: '{Movie Title:DE}', example: 'Titel des Films' },
|
||||
{ token: '{Movie CleanTitle}', example: 'Movies Title' },
|
||||
{ token: '{Movie TitleThe}', example: 'Movie\'s Title, The' },
|
||||
{ token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας' },
|
||||
{ token: '{Movie CleanOriginalTitle}', example: 'Τίτλος ταινίας' },
|
||||
{ token: '{Movie TitleFirstCharacter}', example: 'M' },
|
||||
{ token: '{Movie Collection}', example: 'The Movie Collection' },
|
||||
{ token: '{Movie Certification}', example: 'R' },
|
||||
|
||||
@@ -44,7 +44,14 @@ function filter(items, state) {
|
||||
const predicate = filterPredicates[key];
|
||||
|
||||
if (Array.isArray(value)) {
|
||||
accepted = value.some((v) => predicate(item, v, type));
|
||||
if (
|
||||
type === filterTypes.NOT_CONTAINS ||
|
||||
type === filterTypes.NOT_EQUAL
|
||||
) {
|
||||
accepted = value.every((v) => predicate(item, v, type));
|
||||
} else {
|
||||
accepted = value.some((v) => predicate(item, v, type));
|
||||
}
|
||||
} else {
|
||||
accepted = predicate(item, value, type);
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ class About extends Component {
|
||||
isDocker,
|
||||
runtimeVersion,
|
||||
migrationVersion,
|
||||
databaseVersion,
|
||||
databaseType,
|
||||
appData,
|
||||
startupPath,
|
||||
mode,
|
||||
@@ -68,6 +70,11 @@ class About extends Component {
|
||||
data={migrationVersion}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title={translate('Database')}
|
||||
data={`${titleCase(databaseType)} ${databaseVersion}`}
|
||||
/>
|
||||
|
||||
<DescriptionListItem
|
||||
title={translate('AppDataDirectory')}
|
||||
data={appData}
|
||||
@@ -108,6 +115,8 @@ About.propTypes = {
|
||||
runtimeVersion: PropTypes.string.isRequired,
|
||||
isDocker: PropTypes.bool.isRequired,
|
||||
migrationVersion: PropTypes.number.isRequired,
|
||||
databaseType: PropTypes.string.isRequired,
|
||||
databaseVersion: PropTypes.string.isRequired,
|
||||
appData: PropTypes.string.isRequired,
|
||||
startupPath: PropTypes.string.isRequired,
|
||||
mode: PropTypes.string.isRequired,
|
||||
|
||||
@@ -10,3 +10,7 @@ export function isMobile() {
|
||||
export function isIOS() {
|
||||
return mobileDetect.is('iOS');
|
||||
}
|
||||
|
||||
export function isFirefox() {
|
||||
return window.navigator.userAgent.toLowerCase().indexOf('firefox/') >= 0;
|
||||
}
|
||||
20
package.json
20
package.json
@@ -45,7 +45,7 @@
|
||||
"jquery": "3.6.0",
|
||||
"lodash": "4.17.21",
|
||||
"mobile-detect": "1.4.5",
|
||||
"moment": "2.29.1",
|
||||
"moment": "2.29.2",
|
||||
"mousetrap": "1.6.5",
|
||||
"normalize.css": "8.0.1",
|
||||
"prop-types": "15.7.2",
|
||||
@@ -99,8 +99,8 @@
|
||||
"babel-loader": "8.2.3",
|
||||
"babel-plugin-inline-classnames": "2.0.1",
|
||||
"babel-plugin-transform-react-remove-prop-types": "0.4.24",
|
||||
"core-js": "3.11.0",
|
||||
"css-loader": "5.2.4",
|
||||
"core-js": "3.12.1",
|
||||
"css-loader": "6.5.1",
|
||||
"eslint": "8.11.0",
|
||||
"eslint-plugin-filenames": "1.3.2",
|
||||
"eslint-plugin-import": "2.25.4",
|
||||
@@ -115,22 +115,22 @@
|
||||
"mini-css-extract-plugin": "1.5.0",
|
||||
"postcss": "8.2.12",
|
||||
"postcss-color-function": "4.1.0",
|
||||
"postcss-loader": "5.2.0",
|
||||
"postcss-mixins": "7.0.3",
|
||||
"postcss-nested": "5.0.5",
|
||||
"postcss-loader": "6.2.0",
|
||||
"postcss-mixins": "8.1.0",
|
||||
"postcss-nested": "5.0.6",
|
||||
"postcss-simple-vars": "6.0.3",
|
||||
"postcss-url": "10.1.3",
|
||||
"require-nocache": "1.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"run-sequence": "2.2.1",
|
||||
"streamqueue": "1.1.2",
|
||||
"style-loader": "2.0.0",
|
||||
"style-loader": "3.3.1",
|
||||
"stylelint": "14.6.0",
|
||||
"stylelint-order": "5.0.0",
|
||||
"url-loader": "4.1.1",
|
||||
"webpack": "5.35.1",
|
||||
"webpack-cli": "4.6.0",
|
||||
"webpack-livereload-plugin": "3.0.1",
|
||||
"webpack": "5.64.2",
|
||||
"webpack-cli": "4.9.1",
|
||||
"webpack-livereload-plugin": "3.0.2",
|
||||
"worker-loader": "3.0.8"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ namespace NzbDrone.Automation.Test
|
||||
|
||||
driver.Manage().Window.Size = new System.Drawing.Size(1920, 1080);
|
||||
|
||||
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger());
|
||||
_runner = new NzbDroneRunner(LogManager.GetCurrentClassLogger(), null);
|
||||
_runner.KillAll();
|
||||
_runner.Start();
|
||||
|
||||
|
||||
@@ -63,6 +63,7 @@ namespace NzbDrone.Common.Test.InstrumentationTests
|
||||
[TestCase("Hardlink '/home/mySecret/Downloads/abs.mkv' to '/media/abc.mkv' failed.")]
|
||||
[TestCase("https://notifiarr.com/notifier.php: api=1234530f-422f-4aac-b6b3-01233210aaaa&radarr_health_issue_message=Download")]
|
||||
[TestCase("/readarr/signalr/messages/negotiate?access_token=1234530f422f4aacb6b301233210aaaa&negotiateVersion=1")]
|
||||
[TestCase(@"[Info] MigrationController: *** Migrating Database=radarr-main;Host=postgres14;Username=mySecret;Password=mySecret;Port=5432;Enlist=False ***")]
|
||||
|
||||
// Announce URLs (passkeys) Magnet & Tracker
|
||||
[TestCase(@"magnet_uri"":""magnet:?xt=urn:btih:9pr04sgkillroyimaveql2tyu8xyui&dn=&tr=https%3a%2f%2fxxx.yyy%2f9pr04sg601233210imaveql2tyu8xyui%2fannounce""}")]
|
||||
|
||||
@@ -4,11 +4,13 @@ using DryIoc.Microsoft.DependencyInjection;
|
||||
using FluentAssertions;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Composition.Extensions;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Instrumentation.Extensions;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Extensions;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
@@ -29,7 +31,8 @@ namespace NzbDrone.Common.Test
|
||||
.AddDummyDatabase()
|
||||
.AddStartupContext(new StartupContext("first", "second"));
|
||||
|
||||
container.RegisterInstance<IHostLifetime>(new Mock<IHostLifetime>().Object);
|
||||
container.RegisterInstance(new Mock<IHostLifetime>().Object);
|
||||
container.RegisterInstance(new Mock<IOptions<PostgresOptions>>().Object);
|
||||
|
||||
var serviceProvider = container.GetServiceProvider();
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
@@ -51,78 +50,5 @@ namespace NzbDrone.Common.EnvironmentInfo
|
||||
{
|
||||
return _version;
|
||||
}
|
||||
|
||||
private static Version GetDotNetVersion()
|
||||
{
|
||||
try
|
||||
{
|
||||
const string subkey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full\";
|
||||
using (var ndpKey = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry32).OpenSubKey(subkey))
|
||||
{
|
||||
if (ndpKey == null)
|
||||
{
|
||||
return new Version(4, 0);
|
||||
}
|
||||
|
||||
var releaseKey = (int)ndpKey.GetValue("Release");
|
||||
|
||||
if (releaseKey >= 528040)
|
||||
{
|
||||
return new Version(4, 8, 0);
|
||||
}
|
||||
|
||||
if (releaseKey >= 461808)
|
||||
{
|
||||
return new Version(4, 7, 2);
|
||||
}
|
||||
|
||||
if (releaseKey >= 461308)
|
||||
{
|
||||
return new Version(4, 7, 1);
|
||||
}
|
||||
|
||||
if (releaseKey >= 460798)
|
||||
{
|
||||
return new Version(4, 7);
|
||||
}
|
||||
|
||||
if (releaseKey >= 394802)
|
||||
{
|
||||
return new Version(4, 6, 2);
|
||||
}
|
||||
|
||||
if (releaseKey >= 394254)
|
||||
{
|
||||
return new Version(4, 6, 1);
|
||||
}
|
||||
|
||||
if (releaseKey >= 393295)
|
||||
{
|
||||
return new Version(4, 6);
|
||||
}
|
||||
|
||||
if (releaseKey >= 379893)
|
||||
{
|
||||
return new Version(4, 5, 2);
|
||||
}
|
||||
|
||||
if (releaseKey >= 378675)
|
||||
{
|
||||
return new Version(4, 5, 1);
|
||||
}
|
||||
|
||||
if (releaseKey >= 378389)
|
||||
{
|
||||
return new Version(4, 5);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("Couldnt get .NET framework version: " + ex.ToString());
|
||||
}
|
||||
|
||||
return new Version(4, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ namespace NzbDrone.Common.Instrumentation
|
||||
new Regex(@"iptorrents\.com/[/a-z0-9?&;]*?(?:[?&;](u|tp)=(?<secret>[^&=;]+?))+(?= |;|&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||
new Regex(@"/fetch/[a-z0-9]{32}/(?<secret>[a-z0-9]{32})", RegexOptions.Compiled),
|
||||
new Regex(@"getnzb.*?(?<=\?|&)(r)=(?<secret>[^&=]+?)(?= |&|$)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||
new Regex(@"(?<=[?& ;])[^=]*?(_?(?<!use|get_)token|username|passwo?rd)=(?<secret>[^&=]+?)(?= |&|$|;)", RegexOptions.Compiled | RegexOptions.IgnoreCase),
|
||||
|
||||
// Trackers Announce Keys; Designed for Qbit Json; should work for all in theory
|
||||
new Regex(@"announce(\.php)?(/|%2f|%3fpasskey%3d)(?<secret>[a-z0-9]{16,})|(?<secret>[a-z0-9]{16,})(/|%2f)announce"),
|
||||
|
||||
@@ -127,7 +127,18 @@ namespace NzbDrone.Common.Processes
|
||||
try
|
||||
{
|
||||
_logger.Trace("Setting environment variable '{0}' to '{1}'", environmentVariable.Key, environmentVariable.Value);
|
||||
startInfo.EnvironmentVariables.Add(environmentVariable.Key.ToString(), environmentVariable.Value.ToString());
|
||||
|
||||
var key = environmentVariable.Key.ToString();
|
||||
var value = environmentVariable.Value?.ToString();
|
||||
|
||||
if (startInfo.EnvironmentVariables.ContainsKey(key))
|
||||
{
|
||||
startInfo.EnvironmentVariables[key] = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
startInfo.EnvironmentVariables.Add(key, value);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
@@ -309,7 +320,6 @@ namespace NzbDrone.Common.Processes
|
||||
processInfo = new ProcessInfo();
|
||||
processInfo.Id = process.Id;
|
||||
processInfo.Name = process.ProcessName;
|
||||
processInfo.StartPath = GetExeFileName(process);
|
||||
|
||||
if (process.Id != GetCurrentProcessId() && process.HasExited)
|
||||
{
|
||||
@@ -324,16 +334,6 @@ namespace NzbDrone.Common.Processes
|
||||
return processInfo;
|
||||
}
|
||||
|
||||
private static string GetExeFileName(Process process)
|
||||
{
|
||||
if (process.MainModule.FileName != "mono.exe")
|
||||
{
|
||||
return process.MainModule.FileName;
|
||||
}
|
||||
|
||||
return process.Modules.Cast<ProcessModule>().FirstOrDefault(module => module.ModuleName.ToLower().EndsWith(".exe")).FileName;
|
||||
}
|
||||
|
||||
private List<Process> GetProcessesByName(string name)
|
||||
{
|
||||
var processes = Process.GetProcessesByName(name).ToList();
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
<PackageReference Include="System.Runtime.Loader" Version="4.3.0" />
|
||||
<PackageReference Include="System.ServiceProcess.ServiceController" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="EnsureThat\Resources\ExceptionMessages.Designer.cs">
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void SingleOrDefault_should_return_null_on_empty_db()
|
||||
{
|
||||
Mocker.Resolve<IDatabase>()
|
||||
.OpenConnection().Query<Movie>("SELECT * FROM Movies")
|
||||
.OpenConnection().Query<Movie>("SELECT * FROM \"Movies\"")
|
||||
.SingleOrDefault()
|
||||
.Should()
|
||||
.BeNull();
|
||||
|
||||
@@ -135,9 +135,9 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
private List<Profile147> QueryItems(IDirectDataMapper db)
|
||||
{
|
||||
var test = db.Query("SELECT * FROM Profiles");
|
||||
var test = db.Query("SELECT * FROM \"Profiles\"");
|
||||
|
||||
var items = db.Query<Profile147>("SELECT FormatItems, FormatCutoff FROM Profiles");
|
||||
var items = db.Query<Profile147>("SELECT \"FormatItems\", \"FormatCutoff\" FROM \"Profiles\"");
|
||||
|
||||
return items.Select(i =>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json;
|
||||
@@ -77,7 +77,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
private List<CustomFormatTest149> QueryItems(IDirectDataMapper db)
|
||||
{
|
||||
var items = db.Query<CustomFormatTest149>("SELECT Name, FormatTags FROM CustomFormats");
|
||||
var items = db.Query<CustomFormatTest149>("SELECT \"Name\", \"FormatTags\" FROM \"CustomFormats\"");
|
||||
|
||||
return items.Select(i =>
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json;
|
||||
@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
private List<regex_required_tagsFixture.CustomFormatTest149> QueryItems(IDirectDataMapper db)
|
||||
{
|
||||
var items = db.Query<regex_required_tagsFixture.CustomFormatTest149>("SELECT Name, FormatTags FROM CustomFormats");
|
||||
var items = db.Query<regex_required_tagsFixture.CustomFormatTest149>("SELECT \"Name\", \"FormatTags\" FROM \"CustomFormats\"");
|
||||
|
||||
return items.Select(i =>
|
||||
{
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
Monitored = true,
|
||||
Title = "My Movie",
|
||||
CleanTitle = "mytitle",
|
||||
Status = MovieStatusType.Announced,
|
||||
MinimumAvailability = MovieStatusType.Announced,
|
||||
Status = (int)MovieStatusType.Announced,
|
||||
MinimumAvailability = (int)MovieStatusType.Announced,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
HasPreDBEntry = false,
|
||||
PathState = 1,
|
||||
@@ -112,7 +112,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "My.Movie.2018.German.BluRay-Radarr", "Japanese");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -130,7 +130,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "My.Movie.2018.German.BluRay-Radarr", "Japanese / French");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(2);
|
||||
@@ -149,7 +149,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "My.Movie.2018.German.BluRay-Radarr", "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "My.Movie.2018.German.BluRay-Radarr", "English (USA)");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -184,7 +184,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "", "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -201,7 +201,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, null, null);
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -218,7 +218,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "My.Movie.2018.BluRay-Radarr", "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -235,7 +235,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, "", "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM MovieFiles");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -253,7 +253,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddHistory(c, "My.Movie.2018.Italian.BluRay-Radarr");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM History");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"History\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -270,7 +270,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddHistory(c, "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM History");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"History\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -287,7 +287,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddHistory(c, "Man on Fire");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM History");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"History\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -305,7 +305,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddHistory(c, "My.Movie.2018.Italian.BluRay-Radarr");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM History");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"History\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(3);
|
||||
@@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddBlacklist(c, "My.Movie.2018.Italian.BluRay-Radarr");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM Blacklist");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"Blacklist\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -341,7 +341,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddBlacklist(c, "");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM Blacklist");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"Blacklist\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
@@ -358,7 +358,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddBlacklist(c, "Man on Fire");
|
||||
});
|
||||
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT Id, Languages FROM Blacklist");
|
||||
var items = db.Query<ModelWithLanguages154>("SELECT \"Id\", \"Languages\" FROM \"Blacklist\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Languages.Count.Should().Be(1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using NUnit.Framework;
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings156
|
||||
@@ -31,7 +31,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Priority.Should().Be(1);
|
||||
@@ -44,7 +44,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings156
|
||||
@@ -56,7 +56,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
ConfigContract = "DelugeSettings"
|
||||
}).Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "Deluge2",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings156
|
||||
@@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
ConfigContract = "DelugeSettings"
|
||||
}).Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "sab",
|
||||
Implementation = "Sabnzbd",
|
||||
Settings = new SabnzbdSettings156
|
||||
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(3);
|
||||
items[0].Priority.Should().Be(1);
|
||||
@@ -95,7 +95,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 0,
|
||||
Enable = false,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings156
|
||||
@@ -107,7 +107,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
ConfigContract = "DelugeSettings"
|
||||
}).Row(new
|
||||
{
|
||||
Enable = 0,
|
||||
Enable = false,
|
||||
Name = "Deluge2",
|
||||
Implementation = "Deluge",
|
||||
Settings = new DelugeSettings156
|
||||
@@ -119,7 +119,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
ConfigContract = "DelugeSettings"
|
||||
}).Row(new
|
||||
{
|
||||
Enable = 0,
|
||||
Enable = false,
|
||||
Name = "sab",
|
||||
Implementation = "Sabnzbd",
|
||||
Settings = new SabnzbdSettings156
|
||||
@@ -131,7 +131,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition132>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(3);
|
||||
items[0].Priority.Should().Be(1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Linq;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile159>("SELECT Items FROM Profiles LIMIT 1");
|
||||
var profiles = db.Query<Profile159>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(5);
|
||||
@@ -57,7 +57,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile159>("SELECT Items FROM Profiles LIMIT 1");
|
||||
var profiles = db.Query<Profile159>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Should().HaveCount(5);
|
||||
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile159>("SELECT Items FROM Profiles LIMIT 1");
|
||||
var profiles = db.Query<Profile159>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
|
||||
|
||||
var items = profiles.First().Items;
|
||||
items.Count(c => c.Id == 1001).Should().Be(1);
|
||||
@@ -104,7 +104,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var profiles = db.Query<Profile159>("SELECT Items FROM Profiles LIMIT 1");
|
||||
var profiles = db.Query<Profile159>("SELECT \"Items\" FROM \"Profiles\" LIMIT 1");
|
||||
var items = profiles.First().Items;
|
||||
|
||||
items[1].Items.First().Quality.Should().Be((int)Quality.WEBRip480p);
|
||||
|
||||
@@ -81,14 +81,14 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
""imdbId"": """"
|
||||
}",
|
||||
Release = "{}",
|
||||
Reason = PendingReleaseReason.Delay
|
||||
Reason = (int)PendingReleaseReason.Delay
|
||||
});
|
||||
});
|
||||
|
||||
var json = db.Query<string>("SELECT ParsedMovieInfo FROM PendingReleases").First();
|
||||
var json = db.Query<string>("SELECT \"ParsedMovieInfo\" FROM \"PendingReleases\"").First();
|
||||
json.Should().NotContain("customFormats");
|
||||
|
||||
var pending = db.Query<ParsedMovieInfo>("SELECT ParsedMovieInfo FROM PendingReleases").First();
|
||||
var pending = db.Query<ParsedMovieInfo>("SELECT \"ParsedMovieInfo\" FROM \"PendingReleases\"").First();
|
||||
pending.Quality.Quality.Should().Be(Quality.Bluray1080p);
|
||||
pending.Languages.Should().BeEmpty();
|
||||
}
|
||||
@@ -129,15 +129,15 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
""imdbId"": """"
|
||||
}",
|
||||
Release = "{}",
|
||||
Reason = PendingReleaseReason.Delay
|
||||
Reason = (int)PendingReleaseReason.Delay
|
||||
});
|
||||
});
|
||||
|
||||
var json = db.Query<string>("SELECT ParsedMovieInfo FROM PendingReleases").First();
|
||||
var json = db.Query<string>("SELECT \"ParsedMovieInfo\" FROM \"PendingReleases\"").First();
|
||||
json.Should().NotContain("customFormats");
|
||||
json.Should().NotContain("resolution");
|
||||
|
||||
var pending = db.Query<ParsedMovieInfo>("SELECT ParsedMovieInfo FROM PendingReleases").First();
|
||||
var pending = db.Query<ParsedMovieInfo>("SELECT \"ParsedMovieInfo\" FROM \"PendingReleases\"").First();
|
||||
pending.Quality.Quality.Should().Be(Quality.Bluray1080p);
|
||||
pending.Languages.Should().BeEquivalentTo(new List<Language> { Language.English });
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var json = db.Query<string>("SELECT Specifications FROM CustomFormats").First();
|
||||
var json = db.Query<string>("SELECT \"Specifications\" FROM \"CustomFormats\"").First();
|
||||
|
||||
ValidateFormatTag(json, "ReleaseTitleSpecification", false, false);
|
||||
json.Should().Contain($"\"name\": \"Test\"");
|
||||
@@ -99,7 +99,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var json = db.Query<string>("SELECT Specifications FROM CustomFormats").First();
|
||||
var json = db.Query<string>("SELECT \"Specifications\" FROM \"CustomFormats\"").First();
|
||||
|
||||
ValidateFormatTag(json, "ReleaseTitleSpecification", false, false);
|
||||
ValidateFormatTag(json, "EditionSpecification", false, false);
|
||||
|
||||
@@ -19,12 +19,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("NetImport").Row(new
|
||||
{
|
||||
Enabled = 1,
|
||||
EnableAuto = 1,
|
||||
Enabled = true,
|
||||
EnableAuto = true,
|
||||
RootFolderPath = "D:\\Movies",
|
||||
ProfileId = 1,
|
||||
MinimumAvailability = 1,
|
||||
ShouldMonitor = 1,
|
||||
ShouldMonitor = true,
|
||||
Name = "IMDB List",
|
||||
Implementation = "RadarrLists",
|
||||
Settings = new RadarrListSettings169
|
||||
@@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM NetImport");
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Implementation.Should().Be("RadarrListImport");
|
||||
@@ -52,12 +52,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("NetImport").Row(new
|
||||
{
|
||||
Enabled = 1,
|
||||
EnableAuto = 1,
|
||||
Enabled = true,
|
||||
EnableAuto = true,
|
||||
RootFolderPath = "D:\\Movies",
|
||||
ProfileId = 1,
|
||||
MinimumAvailability = 1,
|
||||
ShouldMonitor = 1,
|
||||
ShouldMonitor = true,
|
||||
Name = "TraktImport",
|
||||
Implementation = "TraktImport",
|
||||
Settings = new TraktSettings169
|
||||
@@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM NetImport");
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Implementation.Should().Be("TraktUserImport");
|
||||
@@ -90,12 +90,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("NetImport").Row(new
|
||||
{
|
||||
Enabled = 1,
|
||||
EnableAuto = 1,
|
||||
Enabled = true,
|
||||
EnableAuto = true,
|
||||
RootFolderPath = "D:\\Movies",
|
||||
ProfileId = 1,
|
||||
MinimumAvailability = 1,
|
||||
ShouldMonitor = 1,
|
||||
ShouldMonitor = true,
|
||||
Name = "TraktImport",
|
||||
Implementation = "TraktImport",
|
||||
Settings = new TraktSettings169
|
||||
@@ -110,7 +110,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM NetImport");
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Implementation.Should().Be("TraktPopularImport");
|
||||
@@ -128,12 +128,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("NetImport").Row(new
|
||||
{
|
||||
Enabled = 1,
|
||||
EnableAuto = 1,
|
||||
Enabled = true,
|
||||
EnableAuto = true,
|
||||
RootFolderPath = "D:\\Movies",
|
||||
ProfileId = 1,
|
||||
MinimumAvailability = 1,
|
||||
ShouldMonitor = 1,
|
||||
ShouldMonitor = true,
|
||||
Name = "TraktImport",
|
||||
Implementation = "TraktImport",
|
||||
Settings = new TraktSettings169
|
||||
@@ -149,7 +149,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM NetImport");
|
||||
var items = db.Query<ListDefinition169>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Implementation.Should().Be("TraktListImport");
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ProviderDefinition166>("SELECT * FROM Notifications");
|
||||
var items = db.Query<ProviderDefinition166>("SELECT * FROM \"Notifications\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Implementation.Should().Be("Email");
|
||||
|
||||
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
}
|
||||
});
|
||||
|
||||
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM NetImport");
|
||||
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(7);
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
}
|
||||
});
|
||||
|
||||
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM NetImport");
|
||||
var items = db.Query<new_list_server.NetImportDefinition178>("SELECT * FROM \"NetImport\"");
|
||||
|
||||
items.Should().HaveCount(5);
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
Items = items.ToJson(),
|
||||
Language = (int)Language.English,
|
||||
MinFormatScore = 0,
|
||||
CutOffFormatScore = 0
|
||||
CutoffFormatScore = 0
|
||||
};
|
||||
|
||||
m.Insert.IntoTable("Profiles").Row(profile);
|
||||
@@ -50,8 +50,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
Monitored = true,
|
||||
Title = movieTitle,
|
||||
CleanTitle = movieTitle,
|
||||
Status = MovieStatusType.Announced,
|
||||
MinimumAvailability = MovieStatusType.Announced,
|
||||
Status = (int)MovieStatusType.Announced,
|
||||
MinimumAvailability = (int)MovieStatusType.Announced,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
HasPreDBEntry = false,
|
||||
@@ -89,8 +89,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie", 123456, profileId);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var profiles = db.Query<Profile179>("SELECT Id FROM Profiles");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
var profiles = db.Query<Profile179>("SELECT \"Id\" FROM \"Profiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
profiles.Should().HaveCount(6);
|
||||
@@ -108,8 +108,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie", 123456, 17);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var profiles = db.Query<Profile179>("SELECT Id FROM Profiles");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
var profiles = db.Query<Profile179>("SELECT \"Id\" FROM \"Profiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
profiles.Should().HaveCount(1);
|
||||
@@ -128,8 +128,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie", 123456, profileId);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var profiles = db.Query<Profile179>("SELECT Id, FormatItems FROM Profiles");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
var profiles = db.Query<Profile179>("SELECT \"Id\", \"FormatItems\" FROM \"Profiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
profiles.Should().HaveCount(6);
|
||||
@@ -149,7 +149,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie", 123456, profileId);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().ProfileId.Should().Be(profileId);
|
||||
@@ -166,7 +166,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie", 123456, 1);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().ProfileId.Should().Be(profileId);
|
||||
@@ -193,7 +193,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, "movie9", 123459, otherProfileId);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie179>("SELECT Id, ProfileId FROM Movies");
|
||||
var items = db.Query<Movie179>("SELECT \"Id\", \"ProfileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(9);
|
||||
items.Where(x => x.ProfileId == commonProfileId).Should().HaveCount(7);
|
||||
|
||||
@@ -20,8 +20,8 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
Monitored = true,
|
||||
Title = movieTitle,
|
||||
CleanTitle = movieTitle,
|
||||
Status = MovieStatusType.Announced,
|
||||
MinimumAvailability = MovieStatusType.Announced,
|
||||
Status = (int)MovieStatusType.Announced,
|
||||
MinimumAvailability = (int)MovieStatusType.Announced,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
HasPreDBEntry = false,
|
||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 4, "movie", "slug3", tmdbId, 0, dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
}
|
||||
@@ -73,7 +73,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 5, "movie2", "slug4", 123457, 0, dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(2);
|
||||
items.Where(i => i.TmdbId == tmdbId).Should().HaveCount(1);
|
||||
@@ -93,7 +93,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 5, "movie5", "slug4", 123457, 0, dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(5);
|
||||
}
|
||||
@@ -112,7 +112,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 4, "movie", "slug3", tmdbId, 0, dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().Id.Should().Be(2);
|
||||
@@ -132,7 +132,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 4, "movie", "slug3", tmdbId, 2, dateAdded, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().MovieFileId.Should().BeGreaterThan(0);
|
||||
@@ -153,7 +153,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovie(c, 4, "movie", "slug3", tmdbId, 0, null, dateAdded);
|
||||
});
|
||||
|
||||
var items = db.Query<Movie185>("SELECT Id, LastInfoSync, TmdbId, MovieFileId FROM Movies");
|
||||
var items = db.Query<Movie185>("SELECT \"Id\", \"LastInfoSync\", \"TmdbId\", \"MovieFileId\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().LastInfoSync.Should().NotBeNull();
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
AddMovieFile(c, 1);
|
||||
});
|
||||
|
||||
var items = db.Query<MovieFile188>("SELECT MediaInfo FROM MovieFiles");
|
||||
var items = db.Query<MovieFile188>("SELECT \"MediaInfo\" FROM \"MovieFiles\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Priority = 1,
|
||||
@@ -34,7 +34,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().RemoveCompletedDownloads.Should().BeFalse();
|
||||
@@ -54,7 +54,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "Deluge",
|
||||
Implementation = "Deluge",
|
||||
Priority = 1,
|
||||
@@ -68,7 +68,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().RemoveCompletedDownloads.Should().BeTrue();
|
||||
@@ -82,7 +82,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("DownloadClients").Row(new
|
||||
{
|
||||
Enable = 1,
|
||||
Enable = true,
|
||||
Name = "RTorrent",
|
||||
Implementation = "RTorrent",
|
||||
Priority = 1,
|
||||
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM DownloadClients");
|
||||
var items = db.Query<DownloadClientDefinition158>("SELECT * FROM \"DownloadClients\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().RemoveCompletedDownloads.Should().BeFalse();
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<NotificationEntity201>("SELECT Id,ConfigContract,Implementation,Name,Settings FROM Notifications");
|
||||
var items = db.Query<NotificationEntity201>("SELECT \"Id\",\"ConfigContract\",\"Implementation\",\"Name\",\"Settings\" FROM \"Notifications\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().ConfigContract.Should().Be("DiscordSettings");
|
||||
|
||||
@@ -20,12 +20,12 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
c.Insert.IntoTable("ImportLists").Row(new
|
||||
{
|
||||
Enabled = 1,
|
||||
EnableAuto = 1,
|
||||
Enabled = true,
|
||||
EnableAuto = true,
|
||||
RootFolderPath = "D:\\Movies",
|
||||
ProfileId = 1,
|
||||
MinimumAvailability = 4,
|
||||
ShouldMonitor = 1,
|
||||
ShouldMonitor = true,
|
||||
Name = "IMDB List",
|
||||
Implementation = "RadarrLists",
|
||||
Settings = new RadarrListSettings169
|
||||
@@ -37,7 +37,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<ListDefinition201>("SELECT Id, MinimumAvailability FROM ImportLists");
|
||||
var items = db.Query<ListDefinition201>("SELECT \"Id\", \"MinimumAvailability\" FROM \"ImportLists\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().MinimumAvailability.Should().Be(3);
|
||||
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
});
|
||||
});
|
||||
|
||||
var items = db.Query<Movie201>("SELECT Id, MinimumAvailability FROM Movies");
|
||||
var items = db.Query<Movie201>("SELECT \"Id\", \"MinimumAvailability\" FROM \"Movies\"");
|
||||
|
||||
items.Should().HaveCount(1);
|
||||
items.First().MinimumAvailability.Should().Be(3);
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Serializer;
|
||||
using NzbDrone.Core.Datastore.Migration;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore.Migration
|
||||
{
|
||||
[TestFixture]
|
||||
public class movie_metadataFixture : MigrationTest<movie_metadata>
|
||||
{
|
||||
[Test]
|
||||
public void should_add_metadata_from_movie_and_link_back_to_movie()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Movies").Row(new
|
||||
{
|
||||
Monitored = true,
|
||||
Title = "Title",
|
||||
CleanTitle = "CleanTitle",
|
||||
Status = 3,
|
||||
MinimumAvailability = 4,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
Runtime = 90,
|
||||
OriginalLanguage = 1,
|
||||
ProfileId = 1,
|
||||
MovieFileId = 0,
|
||||
Path = string.Format("/Movies/{0}", "Title"),
|
||||
TitleSlug = 123456,
|
||||
TmdbId = 132456,
|
||||
Added = DateTime.UtcNow,
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
LastInfoSync = DateTime.UtcNow,
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(132456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Movies\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_link_metadata_to_credits()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Movies").Row(new
|
||||
{
|
||||
Id = 5,
|
||||
Monitored = true,
|
||||
Title = "Title",
|
||||
CleanTitle = "CleanTitle",
|
||||
Status = 3,
|
||||
MinimumAvailability = 4,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
Runtime = 90,
|
||||
OriginalLanguage = 1,
|
||||
ProfileId = 1,
|
||||
MovieFileId = 0,
|
||||
Path = string.Format("/Movies/{0}", "Title"),
|
||||
TitleSlug = 123456,
|
||||
TmdbId = 132456,
|
||||
Added = DateTime.UtcNow,
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
LastInfoSync = DateTime.UtcNow,
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("Credits").Row(new
|
||||
{
|
||||
MovieId = 5,
|
||||
CreditTmdbId = 123,
|
||||
PersonTmdbId = 456,
|
||||
Order = 1,
|
||||
Type = 1,
|
||||
Name = "Some Person",
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson()
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(132456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Credits\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_link_metadata_to_alt_title()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Movies").Row(new
|
||||
{
|
||||
Id = 5,
|
||||
Monitored = true,
|
||||
Title = "Title",
|
||||
CleanTitle = "CleanTitle",
|
||||
Status = 3,
|
||||
MinimumAvailability = 4,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
Runtime = 90,
|
||||
OriginalLanguage = 1,
|
||||
ProfileId = 1,
|
||||
MovieFileId = 0,
|
||||
Path = string.Format("/Movies/{0}", "Title"),
|
||||
TitleSlug = 123456,
|
||||
TmdbId = 132456,
|
||||
Added = DateTime.UtcNow,
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
LastInfoSync = DateTime.UtcNow,
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("AlternativeTitles").Row(new
|
||||
{
|
||||
MovieId = 5,
|
||||
Title = "Some Alt",
|
||||
CleanTitle = "somealt",
|
||||
SourceType = 1,
|
||||
SourceId = 1,
|
||||
Votes = 0,
|
||||
VoteCount = 0,
|
||||
Language = 1
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(132456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"AlternativeTitles\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_link_metadata_to_translation()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Movies").Row(new
|
||||
{
|
||||
Id = 5,
|
||||
Monitored = true,
|
||||
Title = "Title",
|
||||
CleanTitle = "CleanTitle",
|
||||
Status = 3,
|
||||
MinimumAvailability = 4,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
Runtime = 90,
|
||||
OriginalLanguage = 1,
|
||||
ProfileId = 1,
|
||||
MovieFileId = 0,
|
||||
Path = string.Format("/Movies/{0}", "Title"),
|
||||
TitleSlug = 123456,
|
||||
TmdbId = 132456,
|
||||
Added = DateTime.UtcNow,
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
LastInfoSync = DateTime.UtcNow,
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("MovieTranslations").Row(new
|
||||
{
|
||||
MovieId = 5,
|
||||
Title = "Some Trans",
|
||||
Language = 1
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(132456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"MovieTranslations\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_add_metadata_from_list_and_link_back()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("ImportListMovies").Row(new
|
||||
{
|
||||
Title = "Title",
|
||||
Status = 3,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Runtime = 90,
|
||||
TmdbId = 123456,
|
||||
ListId = 4,
|
||||
Translations = new[] { new { } }.ToJson(),
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(123456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_duplicate_metadata()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("Movies").Row(new
|
||||
{
|
||||
Monitored = true,
|
||||
Title = "Title",
|
||||
CleanTitle = "CleanTitle",
|
||||
Status = 3,
|
||||
MinimumAvailability = 4,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Recommendations = new[] { 1 }.ToJson(),
|
||||
Runtime = 90,
|
||||
OriginalLanguage = 1,
|
||||
ProfileId = 1,
|
||||
MovieFileId = 0,
|
||||
Path = string.Format("/Movies/{0}", "Title"),
|
||||
TitleSlug = 123456,
|
||||
TmdbId = 123456,
|
||||
Added = DateTime.UtcNow,
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
LastInfoSync = DateTime.UtcNow,
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("ImportListMovies").Row(new
|
||||
{
|
||||
Title = "Title",
|
||||
Status = 3,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Runtime = 90,
|
||||
TmdbId = 123456,
|
||||
ListId = 4,
|
||||
Translations = new[] { new { } }.ToJson(),
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(123456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var movies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"Movies\"");
|
||||
|
||||
movies.Should().HaveCount(1);
|
||||
movies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
|
||||
var listMovies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
|
||||
|
||||
listMovies.Should().HaveCount(1);
|
||||
listMovies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_duplicate_metadata_from_lists()
|
||||
{
|
||||
var db = WithMigrationTestDb(c =>
|
||||
{
|
||||
c.Insert.IntoTable("ImportListMovies").Row(new
|
||||
{
|
||||
Title = "Title",
|
||||
Overview = "Overview 1",
|
||||
Status = 3,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Runtime = 90,
|
||||
TmdbId = 123456,
|
||||
ListId = 4,
|
||||
Translations = new[] { new { } }.ToJson(),
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
});
|
||||
|
||||
c.Insert.IntoTable("ImportListMovies").Row(new
|
||||
{
|
||||
Title = "Title",
|
||||
Overview = "Overview 2",
|
||||
Status = 3,
|
||||
Images = new[] { new { CoverType = "Poster" } }.ToJson(),
|
||||
Runtime = 90,
|
||||
TmdbId = 123456,
|
||||
ListId = 5,
|
||||
Translations = new[] { new { } }.ToJson(),
|
||||
Collection = new { Name = "Some Collection", TmdbId = 11 }.ToJson(),
|
||||
});
|
||||
});
|
||||
|
||||
var metadata = db.Query<MovieMetadata207>("SELECT \"Id\", \"Title\", \"TmdbId\" FROM \"MovieMetadata\"");
|
||||
|
||||
metadata.Should().HaveCount(1);
|
||||
metadata.First().TmdbId.Should().Be(123456);
|
||||
metadata.First().Title.Should().Be("Title");
|
||||
|
||||
var listMovies = db.Query<Movie207>("SELECT \"Id\", \"MovieMetadataId\" FROM \"ImportListMovies\"");
|
||||
|
||||
listMovies.Should().HaveCount(2);
|
||||
listMovies.First().MovieMetadataId.Should().Be(metadata.First().Id);
|
||||
}
|
||||
}
|
||||
|
||||
public class MovieMetadata207
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int TmdbId { get; set; }
|
||||
public string Title { get; set; }
|
||||
public bool Monitored { get; set; }
|
||||
}
|
||||
|
||||
public class Movie207
|
||||
{
|
||||
public int Id { get; set; }
|
||||
public int MovieMetadataId { get; set; }
|
||||
}
|
||||
}
|
||||
211
src/NzbDrone.Core.Test/Datastore/WhereBuilderPostgresFixture.cs
Normal file
211
src/NzbDrone.Core.Test/Datastore/WhereBuilderPostgresFixture.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Datastore
|
||||
{
|
||||
[TestFixture]
|
||||
public class WhereBuilderPostgresFixture : CoreTest
|
||||
{
|
||||
private WhereBuilderPostgres _subject;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void MapTables()
|
||||
{
|
||||
// Generate table mapping
|
||||
Mocker.Resolve<DbFactory>();
|
||||
}
|
||||
|
||||
private WhereBuilderPostgres Where(Expression<Func<Movie, bool>> filter)
|
||||
{
|
||||
return new WhereBuilderPostgres(filter, true, 0);
|
||||
}
|
||||
|
||||
private WhereBuilderPostgres WhereMeta(Expression<Func<MovieMetadata, bool>> filter)
|
||||
{
|
||||
return new WhereBuilderPostgres(filter, true, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_equal_const()
|
||||
{
|
||||
_subject = Where(x => x.Id == 10);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(10);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_equal_variable()
|
||||
{
|
||||
var id = 10;
|
||||
_subject = Where(x => x.Id == id);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_equal_property()
|
||||
{
|
||||
var movie = new Movie { Id = 10 };
|
||||
_subject = Where(x => x.Id == movie.Id);
|
||||
|
||||
_subject.Parameters.ParameterNames.Should().HaveCount(1);
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = @Clause1_P1)");
|
||||
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(movie.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_equal_joined_property()
|
||||
{
|
||||
_subject = Where(x => x.Profile.Id == 1);
|
||||
|
||||
_subject.Parameters.ParameterNames.Should().HaveCount(1);
|
||||
_subject.ToString().Should().Be($"(\"Profiles\".\"Id\" = @Clause1_P1)");
|
||||
_subject.Parameters.Get<int>("Clause1_P1").Should().Be(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_throws_without_concrete_condition_if_requiresConcreteCondition()
|
||||
{
|
||||
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||
_subject = new WhereBuilderPostgres(filter, true, 0);
|
||||
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_allows_abstract_condition_if_not_requiresConcreteCondition()
|
||||
{
|
||||
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||
_subject = new WhereBuilderPostgres(filter, false, 0);
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = \"Movies\".\"Id\")");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_string_is_null()
|
||||
{
|
||||
_subject = WhereMeta(x => x.CleanTitle == null);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_string_is_null_value()
|
||||
{
|
||||
string cleanTitle = null;
|
||||
_subject = WhereMeta(x => x.CleanTitle == cleanTitle);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_equal_null_property()
|
||||
{
|
||||
var movie = new MovieMetadata { CleanTitle = null };
|
||||
_subject = WhereMeta(x => x.CleanTitle == movie.CleanTitle);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_column_contains_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = WhereMeta(x => x.CleanTitle.Contains(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE '%' || @Clause1_P1 || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_string_contains_column()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = WhereMeta(x => test.Contains(x.CleanTitle));
|
||||
|
||||
_subject.ToString().Should().Be($"(@Clause1_P1 ILIKE '%' || \"MovieMetadata\".\"CleanTitle\" || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_column_starts_with_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = WhereMeta(x => x.CleanTitle.StartsWith(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE @Clause1_P1 || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_column_ends_with_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = WhereMeta(x => x.CleanTitle.EndsWith(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" ILIKE '%' || @Clause1_P1)");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_in_list()
|
||||
{
|
||||
var list = new List<int> { 1, 2, 3 };
|
||||
_subject = Where(x => list.Contains(x.Id));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = ANY (('{{1, 2, 3}}')))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_in_list_2()
|
||||
{
|
||||
var list = new List<int> { 1, 2, 3 };
|
||||
_subject = WhereMeta(x => x.CleanTitle == "test" && list.Contains(x.Id));
|
||||
|
||||
_subject.ToString().Should().Be($"((\"MovieMetadata\".\"CleanTitle\" = @Clause1_P1) AND (\"MovieMetadata\".\"Id\" = ANY (('{{1, 2, 3}}'))))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void postgres_where_in_string_list()
|
||||
{
|
||||
var list = new List<string> { "first", "second", "third" };
|
||||
|
||||
_subject = WhereMeta(x => list.Contains(x.CleanTitle));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" = ANY (@Clause1_P1))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_as_int()
|
||||
{
|
||||
_subject = WhereMeta(x => x.Status == MovieStatusType.Announced);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = @Clause1_P1)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_in_list()
|
||||
{
|
||||
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||
_subject = WhereMeta(x => allowed.Contains(x.Status));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = ANY (@Clause1_P1))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_in_array()
|
||||
{
|
||||
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||
_subject = WhereMeta(x => allowed.Contains(x.Status));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = ANY (@Clause1_P1))");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,9 @@ using NzbDrone.Core.Test.Framework;
|
||||
namespace NzbDrone.Core.Test.Datastore
|
||||
{
|
||||
[TestFixture]
|
||||
public class WhereBuilderFixture : CoreTest
|
||||
public class WhereBuilderSqliteFixture : CoreTest
|
||||
{
|
||||
private WhereBuilder _subject;
|
||||
private WhereBuilderSqlite _subject;
|
||||
|
||||
[OneTimeSetUp]
|
||||
public void MapTables()
|
||||
@@ -22,9 +22,14 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
Mocker.Resolve<DbFactory>();
|
||||
}
|
||||
|
||||
private WhereBuilder Where(Expression<Func<Movie, bool>> filter)
|
||||
private WhereBuilderSqlite Where(Expression<Func<Movie, bool>> filter)
|
||||
{
|
||||
return new WhereBuilder(filter, true, 0);
|
||||
return new WhereBuilderSqlite(filter, true, 0);
|
||||
}
|
||||
|
||||
private WhereBuilderSqlite WhereMeta(Expression<Func<MovieMetadata, bool>> filter)
|
||||
{
|
||||
return new WhereBuilderSqlite(filter, true, 0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -71,7 +76,7 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_throws_without_concrete_condition_if_requiresConcreteCondition()
|
||||
{
|
||||
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||
_subject = new WhereBuilder(filter, true, 0);
|
||||
_subject = new WhereBuilderSqlite(filter, true, 0);
|
||||
Assert.Throws<InvalidOperationException>(() => _subject.ToString());
|
||||
}
|
||||
|
||||
@@ -79,43 +84,43 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_allows_abstract_condition_if_not_requiresConcreteCondition()
|
||||
{
|
||||
Expression<Func<Movie, Movie, bool>> filter = (x, y) => x.Id == y.Id;
|
||||
_subject = new WhereBuilder(filter, false, 0);
|
||||
_subject = new WhereBuilderSqlite(filter, false, 0);
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Id\" = \"Movies\".\"Id\")");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void where_string_is_null()
|
||||
{
|
||||
_subject = Where(x => x.CleanTitle == null);
|
||||
_subject = WhereMeta(x => x.CleanTitle == null);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void where_string_is_null_value()
|
||||
{
|
||||
string cleanTitle = null;
|
||||
_subject = Where(x => x.CleanTitle == cleanTitle);
|
||||
_subject = WhereMeta(x => x.CleanTitle == cleanTitle);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void where_equal_null_property()
|
||||
{
|
||||
var movie = new Movie { CleanTitle = null };
|
||||
_subject = Where(x => x.CleanTitle == movie.CleanTitle);
|
||||
var movie = new MovieMetadata { CleanTitle = null };
|
||||
_subject = WhereMeta(x => x.CleanTitle == movie.CleanTitle);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IS NULL)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IS NULL)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void where_column_contains_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = Where(x => x.CleanTitle.Contains(test));
|
||||
_subject = WhereMeta(x => x.CleanTitle.Contains(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE '%' || @Clause1_P1 || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
@@ -123,9 +128,9 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_string_contains_column()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = Where(x => test.Contains(x.CleanTitle));
|
||||
_subject = WhereMeta(x => test.Contains(x.CleanTitle));
|
||||
|
||||
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"Movies\".\"CleanTitle\" || '%')");
|
||||
_subject.ToString().Should().Be($"(@Clause1_P1 LIKE '%' || \"MovieMetadata\".\"CleanTitle\" || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
@@ -133,9 +138,9 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_column_starts_with_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = Where(x => x.CleanTitle.StartsWith(test));
|
||||
_subject = WhereMeta(x => x.CleanTitle.StartsWith(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE @Clause1_P1 || '%')");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
@@ -143,9 +148,9 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_column_ends_with_string()
|
||||
{
|
||||
var test = "small";
|
||||
_subject = Where(x => x.CleanTitle.EndsWith(test));
|
||||
_subject = WhereMeta(x => x.CleanTitle.EndsWith(test));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" LIKE '%' || @Clause1_P1)");
|
||||
_subject.Parameters.Get<string>("Clause1_P1").Should().Be(test);
|
||||
}
|
||||
|
||||
@@ -164,9 +169,9 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
public void where_in_list_2()
|
||||
{
|
||||
var list = new List<int> { 1, 2, 3 };
|
||||
_subject = Where(x => x.CleanTitle == "test" && list.Contains(x.Id));
|
||||
_subject = WhereMeta(x => x.CleanTitle == "test" && list.Contains(x.Id));
|
||||
|
||||
_subject.ToString().Should().Be($"((\"Movies\".\"CleanTitle\" = @Clause1_P1) AND (\"Movies\".\"Id\" IN (1, 2, 3)))");
|
||||
_subject.ToString().Should().Be($"((\"MovieMetadata\".\"CleanTitle\" = @Clause1_P1) AND (\"MovieMetadata\".\"Id\" IN (1, 2, 3)))");
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -174,35 +179,35 @@ namespace NzbDrone.Core.Test.Datastore
|
||||
{
|
||||
var list = new List<string> { "first", "second", "third" };
|
||||
|
||||
_subject = Where(x => list.Contains(x.CleanTitle));
|
||||
_subject = WhereMeta(x => list.Contains(x.CleanTitle));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"CleanTitle\" IN @Clause1_P1)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"CleanTitle\" IN @Clause1_P1)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_as_int()
|
||||
{
|
||||
_subject = Where(x => x.Status == MovieStatusType.Announced);
|
||||
_subject = WhereMeta(x => x.Status == MovieStatusType.Announced);
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" = @Clause1_P1)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" = @Clause1_P1)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_in_list()
|
||||
{
|
||||
var allowed = new List<MovieStatusType> { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||
_subject = Where(x => allowed.Contains(x.Status));
|
||||
_subject = WhereMeta(x => allowed.Contains(x.Status));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" IN @Clause1_P1)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" IN @Clause1_P1)");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void enum_in_array()
|
||||
{
|
||||
var allowed = new MovieStatusType[] { MovieStatusType.Announced, MovieStatusType.InCinemas };
|
||||
_subject = Where(x => allowed.Contains(x.Status));
|
||||
_subject = WhereMeta(x => allowed.Contains(x.Status));
|
||||
|
||||
_subject.ToString().Should().Be($"(\"Movies\".\"Status\" IN @Clause1_P1)");
|
||||
_subject.ToString().Should().Be($"(\"MovieMetadata\".\"Status\" IN @Clause1_P1)");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -53,7 +53,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[TestCase(60, 1000, false)]
|
||||
public void single_episode(int runtime, int sizeInMegaBytes, bool expectedResult)
|
||||
{
|
||||
_movie.Runtime = runtime;
|
||||
_movie.MovieMetadata.Value.Runtime = runtime;
|
||||
_remoteMovie.Movie = _movie;
|
||||
_remoteMovie.Release.Size = sizeInMegaBytes.Megabytes();
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_return_true_if_size_is_zero()
|
||||
{
|
||||
_movie.Runtime = 120;
|
||||
_movie.MovieMetadata.Value.Runtime = 120;
|
||||
_remoteMovie.Movie = _movie;
|
||||
_remoteMovie.Release.Size = 0;
|
||||
_qualityType.MinSize = 10;
|
||||
@@ -75,7 +75,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_return_true_if_unlimited_30_minute()
|
||||
{
|
||||
_movie.Runtime = 30;
|
||||
_movie.MovieMetadata.Value.Runtime = 30;
|
||||
_remoteMovie.Movie = _movie;
|
||||
_remoteMovie.Release.Size = 18457280000;
|
||||
_qualityType.MaxSize = null;
|
||||
@@ -86,7 +86,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_return_true_if_unlimited_60_minute()
|
||||
{
|
||||
_movie.Runtime = 60;
|
||||
_movie.MovieMetadata.Value.Runtime = 60;
|
||||
_remoteMovie.Movie = _movie;
|
||||
_remoteMovie.Release.Size = 36857280000;
|
||||
_qualityType.MaxSize = null;
|
||||
@@ -97,7 +97,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
[Test]
|
||||
public void should_use_110_minutes_if_runtime_is_0()
|
||||
{
|
||||
_movie.Runtime = 0;
|
||||
_movie.MovieMetadata.Value.Runtime = 0;
|
||||
_remoteMovie.Movie = _movie;
|
||||
_remoteMovie.Release.Size = 1095.Megabytes();
|
||||
|
||||
|
||||
@@ -31,7 +31,10 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
{
|
||||
Language = Language.English
|
||||
},
|
||||
OriginalLanguage = Language.French
|
||||
MovieMetadata = new MovieMetadata
|
||||
{
|
||||
OriginalLanguage = Language.French
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
MinFormatScore = 0
|
||||
})
|
||||
.With(m => m.Title = "A Movie")
|
||||
.With(m => m.Runtime = runtime).Build();
|
||||
.With(m => m.MovieMetadata.Value.Runtime = runtime).Build();
|
||||
|
||||
remoteMovie.Release = new ReleaseInfo();
|
||||
remoteMovie.Release.PublishDate = DateTime.Now.AddDays(-age);
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace NzbDrone.Core.Test.DecisionEngineTests
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<ICustomFormatCalculationService>()
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<ParsedMovieInfo>()))
|
||||
.Setup(x => x.ParseCustomFormat(It.IsAny<ParsedMovieInfo>(), _movie))
|
||||
.Returns(new List<CustomFormat>());
|
||||
}
|
||||
|
||||
|
||||
46
src/NzbDrone.Core.Test/Files/plex_watchlist.json
Normal file
46
src/NzbDrone.Core.Test/Files/plex_watchlist.json
Normal file
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"MediaContainer": {
|
||||
"librarySectionID": "watchlist",
|
||||
"librarySectionTitle": "Watchlist",
|
||||
"offset": 0,
|
||||
"totalSize": 3,
|
||||
"identifier": "tv.plex.provider.metadata",
|
||||
"size": 3,
|
||||
"Metadata": [
|
||||
{
|
||||
"type": "movie",
|
||||
"title": "Arrival",
|
||||
"year": 2016,
|
||||
"Guid": [
|
||||
{
|
||||
"id": "imdb://tt2543164"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "movie",
|
||||
"title": "The Last Witch Hunter",
|
||||
"year": 2015,
|
||||
"Guid": [
|
||||
{
|
||||
"id": "imdb://tt1618442"
|
||||
},
|
||||
{
|
||||
"id": "tmdb://274854"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "movie",
|
||||
"title": "Avengers: Endgame",
|
||||
"year": 2019,
|
||||
"Guid": []
|
||||
},
|
||||
{
|
||||
"type": "movie",
|
||||
"title": "Avengers",
|
||||
"year": 2005
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,18 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.SQLite;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Npgsql;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Test.Common.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.Test.Framework
|
||||
{
|
||||
@@ -49,6 +53,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
public abstract class DbTest : CoreTest
|
||||
{
|
||||
private ITestDatabase _db;
|
||||
private DatabaseType _databaseType;
|
||||
|
||||
protected virtual MigrationType MigrationType => MigrationType.Main;
|
||||
|
||||
@@ -101,17 +106,39 @@ namespace NzbDrone.Core.Test.Framework
|
||||
|
||||
private IDatabase CreateDatabase(MigrationContext migrationContext)
|
||||
{
|
||||
if (_databaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
CreatePostgresDb();
|
||||
}
|
||||
|
||||
var factory = Mocker.Resolve<DbFactory>();
|
||||
|
||||
// If a special migration test or log migration then create new
|
||||
if (migrationContext.BeforeMigration != null)
|
||||
if (migrationContext.BeforeMigration != null || _databaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
return factory.Create(migrationContext);
|
||||
}
|
||||
|
||||
return CreateSqliteDatabase(factory, migrationContext);
|
||||
}
|
||||
|
||||
private void CreatePostgresDb()
|
||||
{
|
||||
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
|
||||
PostgresDatabase.Create(options, MigrationType);
|
||||
}
|
||||
|
||||
private void DropPostgresDb()
|
||||
{
|
||||
var options = Mocker.Resolve<IOptions<PostgresOptions>>().Value;
|
||||
PostgresDatabase.Drop(options, MigrationType);
|
||||
}
|
||||
|
||||
private IDatabase CreateSqliteDatabase(IDbFactory factory, MigrationContext migrationContext)
|
||||
{
|
||||
// Otherwise try to use a cached migrated db
|
||||
var cachedDb = GetCachedDatabase(migrationContext.MigrationType);
|
||||
var testDb = GetTestDb(migrationContext.MigrationType);
|
||||
var cachedDb = SqliteDatabase.GetCachedDb(migrationContext.MigrationType);
|
||||
var testDb = GetTestSqliteDb(migrationContext.MigrationType);
|
||||
if (File.Exists(cachedDb))
|
||||
{
|
||||
TestLogger.Info($"Using cached initial database {cachedDb}");
|
||||
@@ -131,12 +158,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCachedDatabase(MigrationType type)
|
||||
{
|
||||
return Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_{type}.db");
|
||||
}
|
||||
|
||||
private string GetTestDb(MigrationType type)
|
||||
private string GetTestSqliteDb(MigrationType type)
|
||||
{
|
||||
return type == MigrationType.Main ? TestFolderInfo.GetDatabase() : TestFolderInfo.GetLogDatabase();
|
||||
}
|
||||
@@ -151,6 +173,13 @@ namespace NzbDrone.Core.Test.Framework
|
||||
WithTempAsAppPath();
|
||||
SetupLogging();
|
||||
|
||||
// populate the possible postgres options
|
||||
var postgresOptions = PostgresDatabase.GetTestOptions();
|
||||
_databaseType = postgresOptions.Host.IsNotNullOrWhiteSpace() ? DatabaseType.PostgreSQL : DatabaseType.SQLite;
|
||||
|
||||
// Set up remaining container services
|
||||
Mocker.SetConstant(Options.Create(postgresOptions));
|
||||
Mocker.SetConstant<IConfigFileProvider>(Mocker.Resolve<ConfigFileProvider>());
|
||||
Mocker.SetConstant<IConnectionStringFactory>(Mocker.Resolve<ConnectionStringFactory>());
|
||||
Mocker.SetConstant<IMigrationController>(Mocker.Resolve<MigrationController>());
|
||||
|
||||
@@ -170,12 +199,19 @@ namespace NzbDrone.Core.Test.Framework
|
||||
// Make sure there are no lingering connections. (When this happens it means we haven't disposed something properly)
|
||||
GC.Collect();
|
||||
GC.WaitForPendingFinalizers();
|
||||
|
||||
SQLiteConnection.ClearAllPools();
|
||||
NpgsqlConnection.ClearAllPools();
|
||||
|
||||
if (TestFolderInfo != null)
|
||||
{
|
||||
DeleteTempFolder(TestFolderInfo.AppDataFolder);
|
||||
}
|
||||
|
||||
if (_databaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
DropPostgresDb();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
using System.IO;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Datastore.Migration.Framework;
|
||||
using NzbDrone.Test.Common.Datastore;
|
||||
|
||||
namespace NzbDrone.Core.Test
|
||||
{
|
||||
@@ -10,13 +12,13 @@ namespace NzbDrone.Core.Test
|
||||
[OneTimeTearDown]
|
||||
public void ClearCachedDatabase()
|
||||
{
|
||||
var mainCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Main.db");
|
||||
var mainCache = SqliteDatabase.GetCachedDb(MigrationType.Main);
|
||||
if (File.Exists(mainCache))
|
||||
{
|
||||
File.Delete(mainCache);
|
||||
}
|
||||
|
||||
var logCache = Path.Combine(TestContext.CurrentContext.TestDirectory, $"cached_Log.db");
|
||||
var logCache = SqliteDatabase.GetCachedDb(MigrationType.Log);
|
||||
if (File.Exists(logCache))
|
||||
{
|
||||
File.Delete(logCache);
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace NzbDrone.Core.Test.Framework
|
||||
where T : ModelBase, new();
|
||||
IDirectDataMapper GetDirectDataMapper();
|
||||
IDbConnection OpenConnection();
|
||||
DatabaseType DatabaseType { get; }
|
||||
}
|
||||
|
||||
public class TestDatabase : ITestDatabase
|
||||
@@ -30,6 +31,8 @@ namespace NzbDrone.Core.Test.Framework
|
||||
private readonly IDatabase _dbConnection;
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
|
||||
public DatabaseType DatabaseType => _dbConnection.DatabaseType;
|
||||
|
||||
public TestDatabase(IDatabase dbConnection)
|
||||
{
|
||||
_eventAggregator = new Mock<IEventAggregator>().Object;
|
||||
|
||||
@@ -32,16 +32,16 @@ namespace NzbDrone.Core.Test.HealthCheck.Checks
|
||||
{
|
||||
movie = Builder<Movie>.CreateListOfSize(amount)
|
||||
.All()
|
||||
.With(v => v.Status = MovieStatusType.Released)
|
||||
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Released)
|
||||
.BuildList();
|
||||
}
|
||||
else
|
||||
{
|
||||
movie = Builder<Movie>.CreateListOfSize(amount)
|
||||
.All()
|
||||
.With(v => v.Status = MovieStatusType.Released)
|
||||
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Released)
|
||||
.Random(deleted)
|
||||
.With(v => v.Status = MovieStatusType.Deleted)
|
||||
.With(v => v.MovieMetadata.Value.Status = MovieStatusType.Deleted)
|
||||
.BuildList();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
public void should_delete_orphaned_alternative_title_items()
|
||||
{
|
||||
var altTitle = Builder<AlternativeTitle>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Language = Language.English)
|
||||
.BuildNew();
|
||||
|
||||
@@ -28,14 +28,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_alternative_title_items()
|
||||
{
|
||||
var movie = Builder<Movie>.CreateNew().BuildNew();
|
||||
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(movie);
|
||||
Db.Insert(movieMetadata);
|
||||
|
||||
var altTitle = Builder<AlternativeTitle>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Language = Language.English)
|
||||
.With(b => b.MovieId = movie.Id)
|
||||
.With(b => b.MovieMetadataId = movieMetadata.Id)
|
||||
.BuildNew();
|
||||
|
||||
Db.Insert(altTitle);
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
public void should_delete_orphaned_credit_items()
|
||||
{
|
||||
var credit = Builder<Credit>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Name = "Some Credit")
|
||||
.BuildNew();
|
||||
|
||||
@@ -27,14 +27,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_credit_items()
|
||||
{
|
||||
var movie = Builder<Movie>.CreateNew().BuildNew();
|
||||
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(movie);
|
||||
Db.Insert(movieMetadata);
|
||||
|
||||
var credit = Builder<Credit>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Name = "Some Credit")
|
||||
.With(b => b.MovieId = movie.Id)
|
||||
.With(b => b.MovieMetadataId = movieMetadata.Id)
|
||||
.BuildNew();
|
||||
|
||||
Db.Insert(credit);
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||
using NzbDrone.Core.ImportLists.ImportListMovies;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Movies.Translations;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
{
|
||||
[TestFixture]
|
||||
public class CleanupOrphanedMovieMetadataFixture : DbTest<CleanupOrphanedMovieMetadata, MovieMetadata>
|
||||
{
|
||||
[Test]
|
||||
public void should_delete_orphaned_movie_metadata_items()
|
||||
{
|
||||
var metadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(metadata);
|
||||
Subject.Clean();
|
||||
AllStoredModels.Should().BeEmpty();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_movie_metadata_items()
|
||||
{
|
||||
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(movieMetadata);
|
||||
|
||||
var movie = Builder<Movie>.CreateNew()
|
||||
.With(b => b.MovieMetadataId = movieMetadata.Id)
|
||||
.BuildNew();
|
||||
|
||||
Db.Insert(movie);
|
||||
|
||||
Subject.Clean();
|
||||
AllStoredModels.Should().HaveCount(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_movie_metadata_items_for_lists()
|
||||
{
|
||||
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(movieMetadata);
|
||||
|
||||
var movie = Builder<ImportListMovie>.CreateNew()
|
||||
.With(b => b.MovieMetadataId = movieMetadata.Id)
|
||||
.BuildNew();
|
||||
|
||||
Db.Insert(movie);
|
||||
|
||||
Subject.Clean();
|
||||
AllStoredModels.Should().HaveCount(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
public void should_delete_orphaned_movie_translation_items()
|
||||
{
|
||||
var translation = Builder<MovieTranslation>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Language = Language.English)
|
||||
.BuildNew();
|
||||
|
||||
@@ -28,14 +28,14 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
[Test]
|
||||
public void should_not_delete_unorphaned_movie_translation_items()
|
||||
{
|
||||
var movie = Builder<Movie>.CreateNew().BuildNew();
|
||||
var movieMetadata = Builder<MovieMetadata>.CreateNew().BuildNew();
|
||||
|
||||
Db.Insert(movie);
|
||||
Db.Insert(movieMetadata);
|
||||
|
||||
var translation = Builder<MovieTranslation>.CreateNew()
|
||||
.With(h => h.MovieId = default)
|
||||
.With(h => h.MovieMetadataId = default)
|
||||
.With(h => h.Language = Language.English)
|
||||
.With(b => b.MovieId = movie.Id)
|
||||
.With(b => b.MovieMetadataId = movieMetadata.Id)
|
||||
.BuildNew();
|
||||
|
||||
Db.Insert(translation);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using FizzWare.NBuilder;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Housekeeping.Housekeepers;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
@@ -41,7 +41,8 @@ namespace NzbDrone.Core.Test.Housekeeping.Housekeepers
|
||||
|
||||
Subject.Clean();
|
||||
|
||||
AllStoredModels.ToList().ForEach(t => t.LastExecution.Should().Be(expectedTime));
|
||||
// BeCloseTo handles Postgres rounding times
|
||||
AllStoredModels.ToList().ForEach(t => t.LastExecution.Should().BeCloseTo(expectedTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,8 +38,8 @@ namespace NzbDrone.Core.Test.ImportListTests
|
||||
.Build().ToList();
|
||||
|
||||
Mocker.GetMock<ISearchForNewMovie>()
|
||||
.Setup(v => v.MapMovieToTmdbMovie(It.IsAny<Movie>()))
|
||||
.Returns<Movie>(m => new Movie { TmdbId = m.TmdbId });
|
||||
.Setup(v => v.MapMovieToTmdbMovie(It.IsAny<MovieMetadata>()))
|
||||
.Returns<MovieMetadata>(m => new MovieMetadata { TmdbId = m.TmdbId });
|
||||
}
|
||||
|
||||
private void GivenList(int id, bool enabled, bool enabledAuto, ImportListFetchResult fetchResult)
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Http;
|
||||
using NzbDrone.Core.ImportLists;
|
||||
using NzbDrone.Core.ImportLists.Plex;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.ImportList.Plex
|
||||
{
|
||||
[TestFixture]
|
||||
public class PlexParserFixture : CoreTest<PlexParser>
|
||||
{
|
||||
private ImportListResponse CreateResponse(string url, string content)
|
||||
{
|
||||
var httpRequest = new HttpRequest(url);
|
||||
var httpResponse = new HttpResponse(httpRequest, new HttpHeader(), Encoding.UTF8.GetBytes(content));
|
||||
|
||||
return new ImportListResponse(new ImportListRequest(httpRequest), httpResponse);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_parse_plex_watchlist()
|
||||
{
|
||||
var json = ReadAllText("Files/plex_watchlist.json");
|
||||
|
||||
var result = Subject.ParseResponse(CreateResponse("https://metadata.provider.plex.tv/library/sections/watchlist/all", json));
|
||||
|
||||
result.First().Title.Should().Be("Arrival");
|
||||
result.First().Year.Should().Be(2016);
|
||||
result.First().ImdbId.Should().Be("tt2543164");
|
||||
result.First().TmdbId.Should().Be(0);
|
||||
|
||||
result[1].TmdbId.Should().Be(274854);
|
||||
result[1].ImdbId.Should().Be("tt1618442");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,7 +45,7 @@ namespace NzbDrone.Core.Test.IndexerSearchTests
|
||||
.Returns(_movie);
|
||||
|
||||
Mocker.GetMock<IMovieTranslationService>()
|
||||
.Setup(s => s.GetAllTranslationsForMovie(It.IsAny<int>()))
|
||||
.Setup(s => s.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
|
||||
.Returns(new List<MovieTranslation>());
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ namespace NzbDrone.Core.Test.MediaCoverTests
|
||||
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
.With(v => v.Id = 2)
|
||||
.With(v => v.Images = new List<MediaCover.MediaCover> { new MediaCover.MediaCover(MediaCoverTypes.Poster, "") })
|
||||
.With(v => v.MovieMetadata.Value.Images = new List<MediaCover.MediaCover> { new MediaCover.MediaCover(MediaCoverTypes.Poster, "") })
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IMovieService>().Setup(m => m.GetMovie(It.Is<int>(id => id == _movie.Id))).Returns(_movie);
|
||||
|
||||
@@ -255,7 +255,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||
|
||||
Mocker.GetMock<IDetectSample>()
|
||||
.Setup(s => s.IsSample(It.IsAny<Movie>(),
|
||||
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
|
||||
It.IsAny<string>()))
|
||||
.Returns(DetectSampleResult.Sample);
|
||||
|
||||
@@ -324,7 +324,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||
.Returns(imported.Select(i => new ImportResult(i)).ToList());
|
||||
|
||||
Mocker.GetMock<IDetectSample>()
|
||||
.Setup(s => s.IsSample(It.IsAny<Movie>(),
|
||||
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
|
||||
It.IsAny<string>()))
|
||||
.Returns(DetectSampleResult.Sample);
|
||||
|
||||
@@ -431,7 +431,7 @@ namespace NzbDrone.Core.Test.MediaFiles
|
||||
.Returns(new List<ImportResult>());
|
||||
|
||||
Mocker.GetMock<IDetectSample>()
|
||||
.Setup(s => s.IsSample(It.IsAny<Movie>(),
|
||||
.Setup(s => s.IsSample(It.IsAny<MovieMetadata>(),
|
||||
It.IsAny<string>()))
|
||||
.Returns(DetectSampleResult.Sample);
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||
public void Setup()
|
||||
{
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
.With(m => m.OriginalLanguage = Language.English)
|
||||
.With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English)
|
||||
.Build();
|
||||
|
||||
_localMovie = Builder<LocalMovie>.CreateNew()
|
||||
@@ -72,7 +72,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport.Aggregation.Aggregators
|
||||
{
|
||||
var result = Subject.Aggregate(_localMovie, null, false);
|
||||
|
||||
result.Languages.Should().Contain(_movie.OriginalLanguage);
|
||||
result.Languages.Should().Contain(_movie.MovieMetadata.Value.OriginalLanguage);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -16,20 +16,20 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
|
||||
[TestFixture]
|
||||
public class DetectSampleFixture : CoreTest<DetectSample>
|
||||
{
|
||||
private Movie _movie;
|
||||
private MovieMetadata _movie;
|
||||
private LocalMovie _localMovie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
_movie = Builder<MovieMetadata>.CreateNew()
|
||||
.With(s => s.Runtime = 30)
|
||||
.Build();
|
||||
|
||||
_localMovie = new LocalMovie
|
||||
{
|
||||
Path = @"C:\Test\30 Rock\30.rock.s01e01.avi",
|
||||
Movie = _movie,
|
||||
Movie = new Movie { MovieMetadata = _movie },
|
||||
Quality = new QualityModel(Quality.HDTV720p)
|
||||
};
|
||||
}
|
||||
@@ -96,7 +96,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
|
||||
{
|
||||
GivenRuntime(120);
|
||||
|
||||
Subject.IsSample(_localMovie.Movie,
|
||||
Subject.IsSample(_localMovie.Movie.MovieMetadata,
|
||||
_localMovie.Path);
|
||||
|
||||
Mocker.GetMock<IVideoFileInfoReader>().Verify(v => v.GetRunTime(It.IsAny<string>()), Times.Once());
|
||||
@@ -152,7 +152,7 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
|
||||
.Setup(s => s.GetRunTime(It.IsAny<string>()))
|
||||
.Returns((TimeSpan?)null);
|
||||
|
||||
Subject.IsSample(_localMovie.Movie,
|
||||
Subject.IsSample(_localMovie.Movie.MovieMetadata,
|
||||
_localMovie.Path).Should().Be(DetectSampleResult.Indeterminate);
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
@@ -160,13 +160,13 @@ namespace NzbDrone.Core.Test.MediaFiles.MovieImport
|
||||
|
||||
private void ShouldBeSample()
|
||||
{
|
||||
Subject.IsSample(_localMovie.Movie,
|
||||
Subject.IsSample(_localMovie.Movie.MovieMetadata,
|
||||
_localMovie.Path).Should().Be(DetectSampleResult.Sample);
|
||||
}
|
||||
|
||||
private void ShouldBeNotSample()
|
||||
{
|
||||
Subject.IsSample(_localMovie.Movie,
|
||||
Subject.IsSample(_localMovie.Movie.MovieMetadata,
|
||||
_localMovie.Path).Should().Be(DetectSampleResult.NotSample);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||
details.Title.Should().Be(title);
|
||||
}
|
||||
|
||||
private void ValidateMovie(Movie movie)
|
||||
private void ValidateMovie(MovieMetadata movie)
|
||||
{
|
||||
movie.Should().NotBeNull();
|
||||
movie.Title.Should().NotBeNullOrWhiteSpace();
|
||||
@@ -41,7 +41,6 @@ namespace NzbDrone.Core.Test.MetadataSource.SkyHook
|
||||
movie.ImdbId.Should().NotBeNullOrWhiteSpace();
|
||||
movie.Studio.Should().NotBeNullOrWhiteSpace();
|
||||
movie.Runtime.Should().BeGreaterThan(0);
|
||||
movie.TitleSlug.Should().NotBeNullOrWhiteSpace();
|
||||
|
||||
//series.TvRageId.Should().BeGreaterThan(0);
|
||||
movie.TmdbId.Should().BeGreaterThan(0);
|
||||
|
||||
@@ -20,14 +20,13 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
[TestFixture]
|
||||
public class AddMovieFixture : CoreTest<AddMovieService>
|
||||
{
|
||||
private Movie _fakeMovie;
|
||||
private MovieMetadata _fakeMovie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_fakeMovie = Builder<Movie>
|
||||
_fakeMovie = Builder<MovieMetadata>
|
||||
.CreateNew()
|
||||
.With(s => s.Path = null)
|
||||
.Build();
|
||||
}
|
||||
|
||||
@@ -35,7 +34,7 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
{
|
||||
Mocker.GetMock<IProvideMovieInfo>()
|
||||
.Setup(s => s.GetMovieInfo(tmdbId))
|
||||
.Returns(new Tuple<Movie, List<Credit>>(_fakeMovie, new List<Credit>()));
|
||||
.Returns(new Tuple<MovieMetadata, List<Credit>>(_fakeMovie, new List<Credit>()));
|
||||
}
|
||||
|
||||
private void GivenValidPath()
|
||||
|
||||
@@ -18,16 +18,17 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
private AlternativeTitle _title2;
|
||||
private AlternativeTitle _title3;
|
||||
|
||||
private Movie _movie;
|
||||
private MovieMetadata _movie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var titles = Builder<AlternativeTitle>.CreateListOfSize(3).All().With(t => t.MovieId = 0).Build();
|
||||
var titles = Builder<AlternativeTitle>.CreateListOfSize(3).All().With(t => t.MovieMetadataId = 0).Build();
|
||||
_title1 = titles[0];
|
||||
_title2 = titles[1];
|
||||
_title3 = titles[2];
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
|
||||
_movie = Builder<MovieMetadata>.CreateNew()
|
||||
.With(m => m.CleanTitle = "myothertitle")
|
||||
.With(m => m.Id = 1)
|
||||
.Build();
|
||||
@@ -35,7 +36,7 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
|
||||
private void GivenExistingTitles(params AlternativeTitle[] titles)
|
||||
{
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Setup(r => r.FindByMovieId(_movie.Id))
|
||||
Mocker.GetMock<IAlternativeTitleRepository>().Setup(r => r.FindByMovieMetadataId(_movie.Id))
|
||||
.Returns(titles.ToList());
|
||||
}
|
||||
|
||||
@@ -72,7 +73,7 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
{
|
||||
GivenExistingTitles();
|
||||
var titles = new List<AlternativeTitle> { _title1 };
|
||||
var movie = Builder<Movie>.CreateNew().With(m => m.CleanTitle = _title1.CleanTitle).Build();
|
||||
var movie = Builder<MovieMetadata>.CreateNew().With(m => m.CleanTitle = _title1.CleanTitle).Build();
|
||||
|
||||
Subject.UpdateTitles(titles, movie);
|
||||
|
||||
@@ -87,8 +88,8 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
|
||||
Subject.UpdateTitles(titles, _movie);
|
||||
|
||||
_title1.MovieId.Should().Be(_movie.Id);
|
||||
_title2.MovieId.Should().Be(_movie.Id);
|
||||
_title1.MovieMetadataId.Should().Be(_movie.Id);
|
||||
_title2.MovieMetadataId.Should().Be(_movie.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -32,18 +32,18 @@ namespace NzbDrone.Core.Test.MovieTests.CreditTests
|
||||
var credits = Builder<Credit>.CreateListOfSize(5)
|
||||
.TheFirst(1)
|
||||
.With(c => c.Id = 0)
|
||||
.With(c => c.MovieId = _movie2.Id)
|
||||
.With(c => c.MovieMetadataId = _movie2.Id)
|
||||
.TheRest()
|
||||
.With(c => c.Id = 0)
|
||||
.With(c => c.MovieId = _movie1.Id)
|
||||
.With(c => c.MovieMetadataId = _movie1.Id)
|
||||
.BuildListOfNew();
|
||||
|
||||
Db.InsertMany(credits);
|
||||
|
||||
Subject.DeleteForMovies(new List<int> { _movie1.Id });
|
||||
|
||||
var removedMovieCredits = Subject.FindByMovieId(_movie1.Id);
|
||||
var nonRemovedMovieCredits = Subject.FindByMovieId(_movie2.Id);
|
||||
var removedMovieCredits = Subject.FindByMovieMetadataId(_movie1.Id);
|
||||
var nonRemovedMovieCredits = Subject.FindByMovieMetadataId(_movie2.Id);
|
||||
|
||||
removedMovieCredits.Should().HaveCount(0);
|
||||
nonRemovedMovieCredits.Should().HaveCount(1);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
@@ -18,25 +18,25 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
private Credit _credit2;
|
||||
private Credit _credit3;
|
||||
|
||||
private Movie _movie;
|
||||
private MovieMetadata _movie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
var credits = Builder<Credit>.CreateListOfSize(3)
|
||||
.All()
|
||||
.With(t => t.MovieId = 0).Build();
|
||||
.With(t => t.MovieMetadataId = 0).Build();
|
||||
|
||||
_credit1 = credits[0];
|
||||
_credit2 = credits[1];
|
||||
_credit3 = credits[2];
|
||||
|
||||
_movie = Builder<Movie>.CreateNew().With(m => m.Id = 1).Build();
|
||||
_movie = Builder<MovieMetadata>.CreateNew().With(m => m.Id = 1).Build();
|
||||
}
|
||||
|
||||
private void GivenExistingCredits(params Credit[] credits)
|
||||
{
|
||||
Mocker.GetMock<ICreditRepository>().Setup(r => r.FindByMovieId(_movie.Id))
|
||||
Mocker.GetMock<ICreditRepository>().Setup(r => r.FindByMovieMetadataId(_movie.Id))
|
||||
.Returns(credits.ToList());
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ namespace NzbDrone.Core.Test.MovieTests.AlternativeTitleServiceTests
|
||||
|
||||
Subject.UpdateCredits(titles, _movie);
|
||||
|
||||
_credit1.MovieId.Should().Be(_movie.Id);
|
||||
_credit2.MovieId.Should().Be(_movie.Id);
|
||||
_credit1.MovieMetadataId.Should().Be(_movie.Id);
|
||||
_credit2.MovieMetadataId.Should().Be(_movie.Id);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
@@ -21,9 +21,9 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
|
||||
private void SetMovieProperties(DateTime? cinema, DateTime? physical, DateTime? digital, MovieStatusType minimumAvailability)
|
||||
{
|
||||
_movie.InCinemas = cinema;
|
||||
_movie.PhysicalRelease = physical;
|
||||
_movie.DigitalRelease = digital;
|
||||
_movie.MovieMetadata.Value.InCinemas = cinema;
|
||||
_movie.MovieMetadata.Value.PhysicalRelease = physical;
|
||||
_movie.MovieMetadata.Value.DigitalRelease = digital;
|
||||
_movie.MinimumAvailability = minimumAvailability;
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
|
||||
namespace NzbDrone.Core.Test.MovieTests.MovieMetadataRepositoryTests
|
||||
{
|
||||
[TestFixture]
|
||||
|
||||
public class MovieMetadataRepositoryFixture : DbTest<MovieMetadataRepository, MovieMetadata>
|
||||
{
|
||||
private MovieMetadataRepository _movieMetadataRepo;
|
||||
private List<MovieMetadata> _metadataList;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_movieMetadataRepo = Mocker.Resolve<MovieMetadataRepository>();
|
||||
_metadataList = Builder<MovieMetadata>.CreateListOfSize(10).All().With(x => x.Id = 0).BuildList();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void upsert_many_should_insert_list_of_new()
|
||||
{
|
||||
var updated = _movieMetadataRepo.UpsertMany(_metadataList);
|
||||
AllStoredModels.Should().HaveCount(_metadataList.Count);
|
||||
updated.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void upsert_many_should_upsert_existing_with_id_0()
|
||||
{
|
||||
var clone = _metadataList.JsonClone();
|
||||
var updated = _movieMetadataRepo.UpsertMany(clone);
|
||||
|
||||
updated.Should().BeTrue();
|
||||
AllStoredModels.Should().HaveCount(_metadataList.Count);
|
||||
|
||||
updated = _movieMetadataRepo.UpsertMany(_metadataList);
|
||||
updated.Should().BeFalse();
|
||||
AllStoredModels.Should().HaveCount(_metadataList.Count);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void upsert_many_should_upsert_mixed_list_of_old_and_new()
|
||||
{
|
||||
var clone = _metadataList.Take(5).ToList().JsonClone();
|
||||
var updated = _movieMetadataRepo.UpsertMany(clone);
|
||||
|
||||
updated.Should().BeTrue();
|
||||
AllStoredModels.Should().HaveCount(clone.Count);
|
||||
|
||||
updated = _movieMetadataRepo.UpsertMany(_metadataList);
|
||||
updated.Should().BeTrue();
|
||||
AllStoredModels.Should().HaveCount(_metadataList.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -19,15 +19,15 @@ namespace NzbDrone.Core.Test.MovieTests.MovieServiceTests
|
||||
{
|
||||
_candidates = Builder<Movie>.CreateListOfSize(3)
|
||||
.TheFirst(1)
|
||||
.With(x => x.CleanTitle = "batman")
|
||||
.With(x => x.MovieMetadata.Value.CleanTitle = "batman")
|
||||
.With(x => x.Year = 2000)
|
||||
.TheNext(1)
|
||||
.With(x => x.CleanTitle = "batman")
|
||||
.With(x => x.MovieMetadata.Value.CleanTitle = "batman")
|
||||
.With(x => x.Year = 1999)
|
||||
.TheRest()
|
||||
.With(x => x.CleanTitle = "darkknight")
|
||||
.With(x => x.MovieMetadata.Value.CleanTitle = "darkknight")
|
||||
.With(x => x.Year = 2008)
|
||||
.With(x => x.AlternativeTitles = new List<AlternativeTitle>
|
||||
.With(x => x.MovieMetadata.Value.AlternativeTitles = new List<AlternativeTitle>
|
||||
{
|
||||
new AlternativeTitle
|
||||
{
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using FizzWare.NBuilder;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Movies;
|
||||
using NzbDrone.Core.Test.Framework;
|
||||
using NzbDrone.Test.Common;
|
||||
|
||||
namespace NzbDrone.Core.Test.MovieTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class MovieTitleSlugValidatorFixture : CoreTest<MovieTitleSlugValidator>
|
||||
{
|
||||
private List<Movie> _movies;
|
||||
private TestValidator<Movie> _validator;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_movies = Builder<Movie>.CreateListOfSize(1)
|
||||
.Build()
|
||||
.ToList();
|
||||
|
||||
_validator = new TestValidator<Movie>
|
||||
{
|
||||
v => v.RuleFor(s => s.TitleSlug).SetValidator(Subject)
|
||||
};
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Setup(s => s.AllMovieTitleSlugs())
|
||||
.Returns(_movies.ToDictionary(m => m.Id, m => m.TitleSlug));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_not_be_valid_if_there_is_an_existing_movie_with_the_same_title_slug()
|
||||
{
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Setup(s => s.GetMovie(_movies.First().Id))
|
||||
.Returns(_movies.First());
|
||||
|
||||
var movie = Builder<Movie>.CreateNew()
|
||||
.With(s => s.Id = 100)
|
||||
.With(s => s.TitleSlug = _movies.First().TitleSlug)
|
||||
.Build();
|
||||
|
||||
_validator.Validate(movie).IsValid.Should().BeFalse();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_valid_if_there_is_not_an_existing_movie_with_the_same_title_slug()
|
||||
{
|
||||
var movie = Builder<Movie>.CreateNew()
|
||||
.With(s => s.TitleSlug = "MyTitleSlug")
|
||||
.Build();
|
||||
|
||||
_validator.Validate(movie).IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_valid_if_there_is_an_existing_movie_with_a_null_title_slug()
|
||||
{
|
||||
_movies.First().TitleSlug = null;
|
||||
|
||||
var movie = Builder<Movie>.CreateNew()
|
||||
.With(s => s.TitleSlug = "MyTitleSlug")
|
||||
.Build();
|
||||
|
||||
_validator.Validate(movie).IsValid.Should().BeTrue();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void should_be_valid_when_updating_an_existing_movie()
|
||||
{
|
||||
_validator.Validate(_movies.First().JsonClone()).IsValid.Should().BeTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,17 +18,26 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
[TestFixture]
|
||||
public class RefreshMovieServiceFixture : CoreTest<RefreshMovieService>
|
||||
{
|
||||
private Movie _movie;
|
||||
private MovieMetadata _movie;
|
||||
private Movie _existingMovie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
_movie = Builder<MovieMetadata>.CreateNew()
|
||||
.With(s => s.Status = MovieStatusType.Released)
|
||||
.Build();
|
||||
|
||||
_existingMovie = Builder<Movie>.CreateNew()
|
||||
.With(s => s.MovieMetadata.Value.Status = MovieStatusType.Released)
|
||||
.Build();
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Setup(s => s.GetMovie(_movie.Id))
|
||||
.Returns(_existingMovie);
|
||||
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Setup(s => s.Get(_movie.Id))
|
||||
.Returns(_movie);
|
||||
|
||||
Mocker.GetMock<IProvideMovieInfo>()
|
||||
@@ -36,11 +45,11 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
.Callback<int>((i) => { throw new MovieNotFoundException(i); });
|
||||
}
|
||||
|
||||
private void GivenNewMovieInfo(Movie movie)
|
||||
private void GivenNewMovieInfo(MovieMetadata movie)
|
||||
{
|
||||
Mocker.GetMock<IProvideMovieInfo>()
|
||||
.Setup(s => s.GetMovieInfo(_movie.TmdbId))
|
||||
.Returns(new Tuple<Movie, List<Credit>>(movie, new List<Credit>()));
|
||||
.Returns(new Tuple<MovieMetadata, List<Credit>>(movie, new List<Credit>()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -53,8 +62,8 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
|
||||
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Verify(v => v.UpdateMovie(It.Is<List<Movie>>(s => s.First().ImdbId == newMovieInfo.ImdbId), true));
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.ImdbId == newMovieInfo.ImdbId)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@@ -62,8 +71,8 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
{
|
||||
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Verify(v => v.UpdateMovie(It.Is<Movie>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
@@ -78,8 +87,8 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
|
||||
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Verify(v => v.UpdateMovie(It.Is<List<Movie>>(s => s.First().TmdbId == newMovieInfo.TmdbId), true));
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.TmdbId == newMovieInfo.TmdbId)));
|
||||
|
||||
ExceptionVerification.ExpectedWarns(1);
|
||||
}
|
||||
@@ -89,8 +98,8 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
{
|
||||
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Verify(v => v.UpdateMovie(It.Is<Movie>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Verify(v => v.Upsert(It.Is<MovieMetadata>(s => s.Status == MovieStatusType.Deleted)), Times.Once());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
@@ -102,8 +111,8 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
|
||||
Subject.Execute(new RefreshMovieCommand(new List<int> { _movie.Id }));
|
||||
|
||||
Mocker.GetMock<IMovieService>()
|
||||
.Verify(v => v.UpdateMovie(It.IsAny<Movie>()), Times.Never());
|
||||
Mocker.GetMock<IMovieMetadataService>()
|
||||
.Verify(v => v.Upsert(It.IsAny<MovieMetadata>()), Times.Never());
|
||||
|
||||
ExceptionVerification.ExpectedErrors(1);
|
||||
}
|
||||
|
||||
@@ -10,12 +10,12 @@ namespace NzbDrone.Core.Test.MovieTests
|
||||
[TestFixture]
|
||||
public class ShouldRefreshMovieFixture : TestBase<ShouldRefreshMovie>
|
||||
{
|
||||
private Movie _movie;
|
||||
private MovieMetadata _movie;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
_movie = Builder<MovieMetadata>.CreateNew()
|
||||
.With(v => v.Status = MovieStatusType.InCinemas)
|
||||
.With(m => m.PhysicalRelease = DateTime.Today.AddDays(-100))
|
||||
.Build();
|
||||
|
||||
@@ -50,7 +50,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
_movie = Builder<Movie>
|
||||
.CreateNew()
|
||||
.With(s => s.Title = "South Park")
|
||||
.With(s => s.OriginalTitle = "South of the Park")
|
||||
.With(s => s.MovieMetadata.Value.OriginalTitle = "South of the Park")
|
||||
.Build();
|
||||
|
||||
_namingConfig = NamingConfig.Default;
|
||||
@@ -70,7 +70,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
.Returns(new List<CustomFormat>());
|
||||
|
||||
Mocker.GetMock<IMovieTranslationService>()
|
||||
.Setup(v => v.GetAllTranslationsForMovie(It.IsAny<int>()))
|
||||
.Setup(v => v.GetAllTranslationsForMovieMetadata(It.IsAny<int>()))
|
||||
.Returns(_movieTranslations);
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
public void should_replace_movie_original_title()
|
||||
{
|
||||
_namingConfig.StandardMovieFormat = "{Movie OriginalTitle}";
|
||||
_movie.OriginalTitle = "South of the Park";
|
||||
_movie.MovieMetadata.Value.OriginalTitle = "South of the Park";
|
||||
|
||||
Subject.BuildFileName(_movie, _movieFile)
|
||||
.Should().Be("South of the Park");
|
||||
@@ -216,7 +216,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
public void should_replace_movie_certification()
|
||||
{
|
||||
_namingConfig.StandardMovieFormat = "{Movie Certification}";
|
||||
_movie.Certification = "R";
|
||||
_movie.MovieMetadata.Value.Certification = "R";
|
||||
|
||||
Subject.BuildFileName(_movie, _movieFile)
|
||||
.Should().Be("R");
|
||||
@@ -226,7 +226,7 @@ namespace NzbDrone.Core.Test.OrganizerTests.FileNameBuilderTests
|
||||
public void should_replace_movie_collection()
|
||||
{
|
||||
_namingConfig.StandardMovieFormat = "{Movie Collection}";
|
||||
_movie.Collection = new MovieCollection { Name = "South Part Collection" };
|
||||
_movie.MovieMetadata.Value.Collection = new MovieCollection { Name = "South Part Collection" };
|
||||
|
||||
Subject.BuildFileName(_movie, _movieFile)
|
||||
.Should().Be("South Part Collection");
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using FluentAssertions;
|
||||
using NUnit.Framework;
|
||||
using NzbDrone.Core.Languages;
|
||||
using NzbDrone.Core.Parser.Augmenters;
|
||||
using NzbDrone.Core.Parser.Model;
|
||||
|
||||
namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests.AugmentersTests
|
||||
{
|
||||
[TestFixture]
|
||||
public class AugmentWithOriginalLanguageFixture : AugmentMovieInfoFixture<AugmentWithOriginalLanguage>
|
||||
{
|
||||
[Test]
|
||||
public void should_add_movie_original_language()
|
||||
{
|
||||
var releaseInfo = new ParsedMovieInfo();
|
||||
var movie = new Movies.Movie
|
||||
{
|
||||
MovieMetadata = new Movies.MovieMetadata
|
||||
{
|
||||
OriginalLanguage = Language.English
|
||||
}
|
||||
};
|
||||
var result = Subject.AugmentMovieInfo(releaseInfo, movie);
|
||||
result.ExtraInfo.Should().ContainKey("OriginalLanguage");
|
||||
result.ExtraInfo["OriginalLanguage"].Should().Be(Language.English);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -36,11 +36,11 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||
{
|
||||
_movie = Builder<Movie>.CreateNew()
|
||||
.With(m => m.Title = "Fack Ju Göthe 2")
|
||||
.With(m => m.CleanTitle = "fackjugoethe2")
|
||||
.With(m => m.MovieMetadata.Value.CleanTitle = "fackjugoethe2")
|
||||
.With(m => m.Year = 2015)
|
||||
.With(m => m.AlternativeTitles = new List<AlternativeTitle> { new AlternativeTitle("Fack Ju Göthe 2: Same same") })
|
||||
.With(m => m.Translations = new List<MovieTranslation> { new MovieTranslation { Title = "Translated Title", CleanTitle = "translatedtitle" } })
|
||||
.With(m => m.OriginalLanguage = Language.English)
|
||||
.With(m => m.MovieMetadata.Value.AlternativeTitles = new List<AlternativeTitle> { new AlternativeTitle("Fack Ju Göthe 2: Same same") })
|
||||
.With(m => m.MovieMetadata.Value.Translations = new List<MovieTranslation> { new MovieTranslation { Title = "Translated Title", CleanTitle = "translatedtitle" } })
|
||||
.With(m => m.MovieMetadata.Value.OriginalLanguage = Language.English)
|
||||
.Build();
|
||||
|
||||
_parsedMovieInfo = new ParsedMovieInfo
|
||||
@@ -66,14 +66,14 @@ namespace NzbDrone.Core.Test.ParserTests.ParsingServiceTests
|
||||
|
||||
_alternativeTitleInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string> { _movie.AlternativeTitles.First().Title },
|
||||
MovieTitles = new List<string> { _movie.MovieMetadata.Value.AlternativeTitles.First().Title },
|
||||
Languages = new List<Language> { Language.English },
|
||||
Year = _movie.Year,
|
||||
};
|
||||
|
||||
_translationTitleInfo = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string> { _movie.Translations.First().Title },
|
||||
MovieTitles = new List<string> { _movie.MovieMetadata.Value.Translations.First().Title },
|
||||
Languages = new List<Language> { Language.English },
|
||||
Year = _movie.Year,
|
||||
};
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
Subject.GetLatestUpdate("develop", new Version(10, 0)).Should().BeNull();
|
||||
}
|
||||
|
||||
[Ignore("Pending linux-x86 release")]
|
||||
[Test]
|
||||
public void finds_update_when_version_lower()
|
||||
{
|
||||
@@ -39,6 +40,7 @@ namespace NzbDrone.Core.Test.UpdateTests
|
||||
Subject.GetLatestUpdate("invalid_branch", new Version(0, 2)).Should().NotBeNull();
|
||||
}
|
||||
|
||||
[Ignore("Pending linux-x86 release")]
|
||||
[Test]
|
||||
public void should_get_recent_updates()
|
||||
{
|
||||
|
||||
@@ -90,6 +90,8 @@ namespace NzbDrone.Core.Backup
|
||||
|
||||
_archiveService.CreateZip(backupPath, _diskProvider.GetFiles(_backupTempFolder, SearchOption.TopDirectoryOnly));
|
||||
|
||||
Cleanup();
|
||||
|
||||
_logger.ProgressDebug("Backup zip created");
|
||||
}
|
||||
|
||||
@@ -188,9 +190,12 @@ namespace NzbDrone.Core.Backup
|
||||
|
||||
private void BackupDatabase()
|
||||
{
|
||||
_logger.ProgressDebug("Backing up database");
|
||||
if (_maindDb.DatabaseType == DatabaseType.SQLite)
|
||||
{
|
||||
_logger.ProgressDebug("Backing up database");
|
||||
|
||||
_makeDatabaseBackup.BackupDatabase(_maindDb, _backupTempFolder);
|
||||
_makeDatabaseBackup.BackupDatabase(_maindDb, _backupTempFolder);
|
||||
}
|
||||
}
|
||||
|
||||
private void BackupConfigFile()
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace NzbDrone.Core.Blocklisting
|
||||
Delete(x => movieIds.Contains(x.MovieId));
|
||||
}
|
||||
|
||||
protected override SqlBuilder PagedBuilder() => new SqlBuilder().Join<Blocklist, Movie>((b, m) => b.MovieId == m.Id);
|
||||
protected override SqlBuilder PagedBuilder() => new SqlBuilder(_database.DatabaseType).Join<Blocklist, Movie>((b, m) => b.MovieId == m.Id);
|
||||
protected override IEnumerable<Blocklist> PagedQuery(SqlBuilder sql) => _database.QueryJoined<Blocklist, Movie>(sql, (bl, movie) =>
|
||||
{
|
||||
bl.Movie = movie;
|
||||
|
||||
@@ -5,12 +5,14 @@ using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
using Microsoft.Extensions.Options;
|
||||
using NzbDrone.Common.Cache;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Authentication;
|
||||
using NzbDrone.Core.Configuration.Events;
|
||||
using NzbDrone.Core.Datastore;
|
||||
using NzbDrone.Core.Lifecycle;
|
||||
using NzbDrone.Core.Messaging.Commands;
|
||||
using NzbDrone.Core.Messaging.Events;
|
||||
@@ -19,7 +21,7 @@ using NzbDrone.Core.Update;
|
||||
namespace NzbDrone.Core.Configuration
|
||||
{
|
||||
public interface IConfigFileProvider : IHandleAsync<ApplicationStartedEvent>,
|
||||
IExecute<ResetApiKeyCommand>
|
||||
IExecute<ResetApiKeyCommand>
|
||||
{
|
||||
XDocument LoadConfigFile();
|
||||
Dictionary<string, object> GetConfigDictionary();
|
||||
@@ -48,6 +50,12 @@ namespace NzbDrone.Core.Configuration
|
||||
string UpdateScriptPath { get; }
|
||||
string SyslogServer { get; }
|
||||
int SyslogPort { get; }
|
||||
string PostgresHost { get; }
|
||||
int PostgresPort { get; }
|
||||
string PostgresUser { get; }
|
||||
string PostgresPassword { get; }
|
||||
string PostgresMainDb { get; }
|
||||
string PostgresLogDb { get; }
|
||||
}
|
||||
|
||||
public class ConfigFileProvider : IConfigFileProvider
|
||||
@@ -57,6 +65,7 @@ namespace NzbDrone.Core.Configuration
|
||||
private readonly IEventAggregator _eventAggregator;
|
||||
private readonly IDiskProvider _diskProvider;
|
||||
private readonly ICached<string> _cache;
|
||||
private readonly PostgresOptions _postgresOptions;
|
||||
|
||||
private readonly string _configFile;
|
||||
private static readonly Regex HiddenCharacterRegex = new Regex("[^a-z0-9]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
|
||||
@@ -66,12 +75,14 @@ namespace NzbDrone.Core.Configuration
|
||||
public ConfigFileProvider(IAppFolderInfo appFolderInfo,
|
||||
ICacheManager cacheManager,
|
||||
IEventAggregator eventAggregator,
|
||||
IDiskProvider diskProvider)
|
||||
IDiskProvider diskProvider,
|
||||
IOptions<PostgresOptions> postgresOptions)
|
||||
{
|
||||
_cache = cacheManager.GetCache<string>(GetType());
|
||||
_eventAggregator = eventAggregator;
|
||||
_diskProvider = diskProvider;
|
||||
_configFile = appFolderInfo.GetConfigPath();
|
||||
_postgresOptions = postgresOptions.Value;
|
||||
}
|
||||
|
||||
public Dictionary<string, object> GetConfigDictionary()
|
||||
@@ -184,6 +195,12 @@ namespace NzbDrone.Core.Configuration
|
||||
|
||||
public string LogLevel => GetValue("LogLevel", "info").ToLowerInvariant();
|
||||
public string ConsoleLogLevel => GetValue("ConsoleLogLevel", string.Empty, persist: false);
|
||||
public string PostgresHost => _postgresOptions?.Host ?? GetValue("PostgresHost", string.Empty, persist: false);
|
||||
public string PostgresUser => _postgresOptions?.User ?? GetValue("PostgresUser", string.Empty, persist: false);
|
||||
public string PostgresPassword => _postgresOptions?.Password ?? GetValue("PostgresPassword", string.Empty, persist: false);
|
||||
public string PostgresMainDb => _postgresOptions?.MainDb ?? GetValue("PostgresMainDb", "radarr-main", persist: false);
|
||||
public string PostgresLogDb => _postgresOptions?.LogDb ?? GetValue("PostgresLogDb", "radarr-log", persist: false);
|
||||
public int PostgresPort => (_postgresOptions?.Port ?? 0) != 0 ? _postgresOptions.Port : GetValueInt("PostgresPort", 5432, persist: false);
|
||||
public bool LogSql => GetValueBoolean("LogSql", false, persist: false);
|
||||
public int LogRotate => GetValueInt("LogRotate", 50, persist: false);
|
||||
public bool FilterSentryEvents => GetValueBoolean("FilterSentryEvents", true, persist: false);
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||
{
|
||||
public interface ICustomFormatCalculationService
|
||||
{
|
||||
List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo);
|
||||
List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie);
|
||||
List<CustomFormat> ParseCustomFormat(MovieFile movieFile);
|
||||
List<CustomFormat> ParseCustomFormat(Blocklist blocklist);
|
||||
List<CustomFormat> ParseCustomFormat(MovieHistory history);
|
||||
@@ -76,27 +76,29 @@ namespace NzbDrone.Core.CustomFormats
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movieFile.Movie.Title },
|
||||
MovieTitles = new List<string>() { movieFile.Movie.MovieMetadata.Value.Title },
|
||||
SimpleReleaseTitle = sceneName.SimplifyReleaseTitle(),
|
||||
Quality = movieFile.Quality,
|
||||
Languages = movieFile.Languages,
|
||||
ReleaseGroup = movieFile.ReleaseGroup,
|
||||
Edition = movieFile.Edition,
|
||||
Year = movieFile.Movie.Year,
|
||||
ImdbId = movieFile.Movie.ImdbId,
|
||||
Year = movieFile.Movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movieFile.Movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", movieFile.IndexerFlags },
|
||||
{ "Size", movieFile.Size },
|
||||
{ "Filename", System.IO.Path.GetFileName(movieFile.RelativePath) }
|
||||
{ "Filename", Path.GetFileName(movieFile.RelativePath) },
|
||||
{ "OriginalLanguage", movieFile.Movie.MovieMetadata.Value.OriginalLanguage }
|
||||
}
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info, allCustomFormats);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo)
|
||||
public List<CustomFormat> ParseCustomFormat(ParsedMovieInfo movieInfo, Movie movie)
|
||||
{
|
||||
movieInfo = _parsingService.EnhanceMovieInfo(movieInfo, new List<object> { movie }) ?? movieInfo;
|
||||
return ParseCustomFormat(movieInfo, _formatService.All());
|
||||
}
|
||||
|
||||
@@ -112,14 +114,14 @@ namespace NzbDrone.Core.CustomFormats
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.Title },
|
||||
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? blocklist.SourceTitle.SimplifyReleaseTitle(),
|
||||
Quality = blocklist.Quality,
|
||||
Languages = blocklist.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup,
|
||||
Edition = parsed?.Edition,
|
||||
Year = movie.Year,
|
||||
ImdbId = movie.ImdbId,
|
||||
Year = movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", blocklist.IndexerFlags },
|
||||
@@ -127,7 +129,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||
}
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info);
|
||||
return ParseCustomFormat(info, movie);
|
||||
}
|
||||
|
||||
public List<CustomFormat> ParseCustomFormat(MovieHistory history)
|
||||
@@ -140,14 +142,14 @@ namespace NzbDrone.Core.CustomFormats
|
||||
|
||||
var info = new ParsedMovieInfo
|
||||
{
|
||||
MovieTitles = new List<string>() { movie.Title },
|
||||
MovieTitles = new List<string>() { movie.MovieMetadata.Value.Title },
|
||||
SimpleReleaseTitle = parsed?.SimpleReleaseTitle ?? history.SourceTitle.SimplifyReleaseTitle(),
|
||||
Quality = history.Quality,
|
||||
Languages = history.Languages,
|
||||
ReleaseGroup = parsed?.ReleaseGroup,
|
||||
Edition = parsed?.Edition,
|
||||
Year = movie.Year,
|
||||
ImdbId = movie.ImdbId,
|
||||
Year = movie.MovieMetadata.Value.Year,
|
||||
ImdbId = movie.MovieMetadata.Value.ImdbId,
|
||||
ExtraInfo = new Dictionary<string, object>
|
||||
{
|
||||
{ "IndexerFlags", flags },
|
||||
@@ -155,7 +157,7 @@ namespace NzbDrone.Core.CustomFormats
|
||||
}
|
||||
};
|
||||
|
||||
return ParseCustomFormat(info);
|
||||
return ParseCustomFormat(info, movie);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,10 @@ namespace NzbDrone.Core.CustomFormats
|
||||
|
||||
protected override bool IsSatisfiedByWithoutNegate(ParsedMovieInfo movieInfo)
|
||||
{
|
||||
return movieInfo?.Languages?.Contains((Language)Value) ?? false;
|
||||
var comparedLanguage = movieInfo != null && Name == "Original" && movieInfo.ExtraInfo.ContainsKey("OriginalLanguage")
|
||||
? (Language)movieInfo.ExtraInfo["OriginalLanguage"]
|
||||
: (Language)Value;
|
||||
return movieInfo?.Languages?.Contains(comparedLanguage) ?? false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace NzbDrone.Core.Datastore
|
||||
_updateSql = GetUpdateSql(_properties);
|
||||
}
|
||||
|
||||
protected virtual SqlBuilder Builder() => new SqlBuilder();
|
||||
protected virtual SqlBuilder Builder() => new SqlBuilder(_database.DatabaseType);
|
||||
|
||||
protected virtual List<TModel> Query(SqlBuilder builder) => _database.Query<TModel>(builder).ToList();
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
using (var conn = _database.OpenConnection())
|
||||
{
|
||||
return conn.ExecuteScalar<int>($"SELECT COUNT(*) FROM {_table}");
|
||||
return conn.ExecuteScalar<int>($"SELECT COUNT(*) FROM \"{_table}\"");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,6 +175,11 @@ namespace NzbDrone.Core.Datastore
|
||||
}
|
||||
}
|
||||
|
||||
if (_database.DatabaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
return $"INSERT INTO \"{_table}\" ({sbColumnList.ToString()}) VALUES ({sbParameterList.ToString()}) RETURNING \"Id\"";
|
||||
}
|
||||
|
||||
return $"INSERT INTO {_table} ({sbColumnList.ToString()}) VALUES ({sbParameterList.ToString()}); SELECT last_insert_rowid() id";
|
||||
}
|
||||
|
||||
@@ -182,7 +187,8 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
SqlBuilderExtensions.LogQuery(_insertSql, model);
|
||||
var multi = connection.QueryMultiple(_insertSql, model, transaction);
|
||||
var id = (int)multi.Read().First().id;
|
||||
var multiRead = multi.Read();
|
||||
var id = (int)(multiRead.First().id ?? multiRead.First().Id);
|
||||
_keyProperty.SetValue(model, id);
|
||||
|
||||
return model;
|
||||
@@ -293,7 +299,7 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
using (var conn = _database.OpenConnection())
|
||||
{
|
||||
conn.Execute($"DELETE FROM [{_table}]");
|
||||
conn.Execute($"DELETE FROM \"{_table}\"");
|
||||
}
|
||||
|
||||
if (vacuum)
|
||||
@@ -352,7 +358,7 @@ namespace NzbDrone.Core.Datastore
|
||||
private string GetUpdateSql(List<PropertyInfo> propertiesToUpdate)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendFormat("UPDATE {0} SET ", _table);
|
||||
sb.AppendFormat("UPDATE \"{0}\" SET ", _table);
|
||||
|
||||
for (var i = 0; i < propertiesToUpdate.Count; i++)
|
||||
{
|
||||
@@ -420,9 +426,10 @@ namespace NzbDrone.Core.Datastore
|
||||
pagingSpec.SortKey = $"{_table}.{_keyProperty.Name}";
|
||||
}
|
||||
|
||||
var sortKey = TableMapping.Mapper.GetSortKey(pagingSpec.SortKey);
|
||||
var sortDirection = pagingSpec.SortDirection == SortDirection.Descending ? "DESC" : "ASC";
|
||||
var pagingOffset = (pagingSpec.Page - 1) * pagingSpec.PageSize;
|
||||
builder.OrderBy($"{pagingSpec.SortKey} {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}");
|
||||
var pagingOffset = Math.Max(pagingSpec.Page - 1, 0) * pagingSpec.PageSize;
|
||||
builder.OrderBy($"\"{sortKey}\" {sortDirection} LIMIT {pagingSpec.PageSize} OFFSET {pagingOffset}");
|
||||
|
||||
return queryFunc(builder).ToList();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
using System;
|
||||
using System.Data.SQLite;
|
||||
using Npgsql;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Extensions;
|
||||
using NzbDrone.Core.Configuration;
|
||||
|
||||
namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
@@ -14,10 +16,17 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public class ConnectionStringFactory : IConnectionStringFactory
|
||||
{
|
||||
public ConnectionStringFactory(IAppFolderInfo appFolderInfo)
|
||||
private readonly IConfigFileProvider _configFileProvider;
|
||||
|
||||
public ConnectionStringFactory(IAppFolderInfo appFolderInfo, IConfigFileProvider configFileProvider)
|
||||
{
|
||||
MainDbConnectionString = GetConnectionString(appFolderInfo.GetDatabase());
|
||||
LogDbConnectionString = GetConnectionString(appFolderInfo.GetLogDatabase());
|
||||
_configFileProvider = configFileProvider;
|
||||
|
||||
MainDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresMainDb) :
|
||||
GetConnectionString(appFolderInfo.GetDatabase());
|
||||
|
||||
LogDbConnectionString = _configFileProvider.PostgresHost.IsNotNullOrWhiteSpace() ? GetPostgresConnectionString(_configFileProvider.PostgresLogDb) :
|
||||
GetConnectionString(appFolderInfo.GetLogDatabase());
|
||||
}
|
||||
|
||||
public string MainDbConnectionString { get; private set; }
|
||||
@@ -48,5 +57,19 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
return connectionBuilder.ConnectionString;
|
||||
}
|
||||
|
||||
private string GetPostgresConnectionString(string dbName)
|
||||
{
|
||||
var connectionBuilder = new NpgsqlConnectionStringBuilder();
|
||||
|
||||
connectionBuilder.Database = dbName;
|
||||
connectionBuilder.Host = _configFileProvider.PostgresHost;
|
||||
connectionBuilder.Username = _configFileProvider.PostgresUser;
|
||||
connectionBuilder.Password = _configFileProvider.PostgresPassword;
|
||||
connectionBuilder.Port = _configFileProvider.PostgresPort;
|
||||
connectionBuilder.Enlist = false;
|
||||
|
||||
return connectionBuilder.ConnectionString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
19
src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs
Normal file
19
src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs
Normal file
@@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using Dapper;
|
||||
|
||||
namespace NzbDrone.Core.Datastore.Converters
|
||||
{
|
||||
public class DapperTimeSpanConverter : SqlMapper.TypeHandler<TimeSpan>
|
||||
{
|
||||
public override void SetValue(IDbDataParameter parameter, TimeSpan value)
|
||||
{
|
||||
parameter.Value = value.ToString();
|
||||
}
|
||||
|
||||
public override TimeSpan Parse(object value)
|
||||
{
|
||||
return TimeSpan.Parse((string)value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Text.RegularExpressions;
|
||||
using Dapper;
|
||||
using NLog;
|
||||
using NzbDrone.Common.Instrumentation;
|
||||
@@ -11,6 +12,7 @@ namespace NzbDrone.Core.Datastore
|
||||
IDbConnection OpenConnection();
|
||||
Version Version { get; }
|
||||
int Migration { get; }
|
||||
DatabaseType DatabaseType { get; }
|
||||
void Vacuum();
|
||||
}
|
||||
|
||||
@@ -32,13 +34,44 @@ namespace NzbDrone.Core.Datastore
|
||||
return _datamapperFactory();
|
||||
}
|
||||
|
||||
public DatabaseType DatabaseType
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var db = _datamapperFactory())
|
||||
{
|
||||
if (db.ConnectionString.Contains(".db"))
|
||||
{
|
||||
return DatabaseType.SQLite;
|
||||
}
|
||||
else
|
||||
{
|
||||
return DatabaseType.PostgreSQL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Version Version
|
||||
{
|
||||
get
|
||||
{
|
||||
using (var db = _datamapperFactory())
|
||||
{
|
||||
var version = db.QueryFirstOrDefault<string>("SELECT sqlite_version()");
|
||||
string version;
|
||||
|
||||
try
|
||||
{
|
||||
version = db.QueryFirstOrDefault<string>("SHOW server_version");
|
||||
|
||||
//Postgres can return extra info about operating system on version call, ignore this
|
||||
version = Regex.Replace(version, @"\(.*?\)", "");
|
||||
}
|
||||
catch
|
||||
{
|
||||
version = db.QueryFirstOrDefault<string>("SELECT sqlite_version()");
|
||||
}
|
||||
|
||||
return new Version(version);
|
||||
}
|
||||
}
|
||||
@@ -50,7 +83,7 @@ namespace NzbDrone.Core.Datastore
|
||||
{
|
||||
using (var db = _datamapperFactory())
|
||||
{
|
||||
return db.QueryFirstOrDefault<int>("SELECT version from VersionInfo ORDER BY version DESC LIMIT 1");
|
||||
return db.QueryFirstOrDefault<int>("SELECT \"Version\" from \"VersionInfo\" ORDER BY \"Version\" DESC LIMIT 1");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,4 +106,10 @@ namespace NzbDrone.Core.Datastore
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public enum DatabaseType
|
||||
{
|
||||
SQLite,
|
||||
PostgreSQL
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
using System;
|
||||
using System.Data.Common;
|
||||
using System.Data.SQLite;
|
||||
using NLog;
|
||||
using Npgsql;
|
||||
using NzbDrone.Common.Disk;
|
||||
using NzbDrone.Common.EnvironmentInfo;
|
||||
using NzbDrone.Common.Exceptions;
|
||||
@@ -85,10 +87,19 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
var db = new Database(migrationContext.MigrationType.ToString(), () =>
|
||||
{
|
||||
var conn = SQLiteFactory.Instance.CreateConnection();
|
||||
conn.ConnectionString = connectionString;
|
||||
conn.Open();
|
||||
DbConnection conn;
|
||||
|
||||
if (connectionString.Contains(".db"))
|
||||
{
|
||||
conn = SQLiteFactory.Instance.CreateConnection();
|
||||
conn.ConnectionString = connectionString;
|
||||
}
|
||||
else
|
||||
{
|
||||
conn = new NpgsqlConnection(connectionString);
|
||||
}
|
||||
|
||||
conn.Open();
|
||||
return conn;
|
||||
});
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public static SqlBuilder Select(this SqlBuilder builder, params Type[] types)
|
||||
{
|
||||
return builder.Select(types.Select(x => TableMapping.Mapper.TableNameMapping(x) + ".*").Join(", "));
|
||||
return builder.Select(types.Select(x => $"\"{TableMapping.Mapper.TableNameMapping(x)}\".*").Join(", "));
|
||||
}
|
||||
|
||||
public static SqlBuilder SelectDistinct(this SqlBuilder builder, params Type[] types)
|
||||
@@ -42,41 +42,41 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public static SqlBuilder Where<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
|
||||
{
|
||||
var wb = new WhereBuilder(filter, true, builder.Sequence);
|
||||
var wb = GetWhereBuilder(builder.DatabaseType, filter, true, builder.Sequence);
|
||||
|
||||
return builder.Where(wb.ToString(), wb.Parameters);
|
||||
}
|
||||
|
||||
public static SqlBuilder OrWhere<TModel>(this SqlBuilder builder, Expression<Func<TModel, bool>> filter)
|
||||
{
|
||||
var wb = new WhereBuilder(filter, true, builder.Sequence);
|
||||
var wb = GetWhereBuilder(builder.DatabaseType, filter, true, builder.Sequence);
|
||||
|
||||
return builder.OrWhere(wb.ToString(), wb.Parameters);
|
||||
}
|
||||
|
||||
public static SqlBuilder Join<TLeft, TRight>(this SqlBuilder builder, Expression<Func<TLeft, TRight, bool>> filter)
|
||||
{
|
||||
var wb = new WhereBuilder(filter, false, builder.Sequence);
|
||||
var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence);
|
||||
|
||||
var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight));
|
||||
|
||||
return builder.Join($"{rightTable} ON {wb.ToString()}");
|
||||
return builder.Join($"\"{rightTable}\" ON {wb.ToString()}");
|
||||
}
|
||||
|
||||
public static SqlBuilder LeftJoin<TLeft, TRight>(this SqlBuilder builder, Expression<Func<TLeft, TRight, bool>> filter)
|
||||
{
|
||||
var wb = new WhereBuilder(filter, false, builder.Sequence);
|
||||
var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence);
|
||||
|
||||
var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight));
|
||||
|
||||
return builder.LeftJoin($"{rightTable} ON {wb.ToString()}");
|
||||
return builder.LeftJoin($"\"{rightTable}\" ON {wb.ToString()}");
|
||||
}
|
||||
|
||||
public static SqlBuilder GroupBy<TModel>(this SqlBuilder builder, Expression<Func<TModel, object>> property)
|
||||
{
|
||||
var table = TableMapping.Mapper.TableNameMapping(typeof(TModel));
|
||||
var propName = property.GetMemberName().Name;
|
||||
return builder.GroupBy($"{table}.{propName}");
|
||||
return builder.GroupBy($"\"{table}\".\"{propName}\"");
|
||||
}
|
||||
|
||||
public static SqlBuilder.Template AddSelectTemplate(this SqlBuilder builder, Type type)
|
||||
@@ -138,6 +138,18 @@ namespace NzbDrone.Core.Datastore
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
private static WhereBuilder GetWhereBuilder(DatabaseType databaseType, Expression filter, bool requireConcrete, int seq)
|
||||
{
|
||||
if (databaseType == DatabaseType.PostgreSQL)
|
||||
{
|
||||
return new WhereBuilderPostgres(filter, requireConcrete, seq);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new WhereBuilderSqlite(filter, requireConcrete, seq);
|
||||
}
|
||||
}
|
||||
|
||||
private static Dictionary<string, object> ToDictionary(this DynamicParameters dynamicParams)
|
||||
{
|
||||
var argsDictionary = new Dictionary<string, object>();
|
||||
|
||||
@@ -10,10 +10,12 @@ namespace NzbDrone.Core.Datastore
|
||||
public class LogDatabase : ILogDatabase
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
private readonly DatabaseType _databaseType;
|
||||
|
||||
public LogDatabase(IDatabase database)
|
||||
{
|
||||
_database = database;
|
||||
_databaseType = _database == null ? DatabaseType.SQLite : _database.DatabaseType;
|
||||
}
|
||||
|
||||
public IDbConnection OpenConnection()
|
||||
@@ -25,6 +27,8 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public int Migration => _database.Migration;
|
||||
|
||||
public DatabaseType DatabaseType => _databaseType;
|
||||
|
||||
public void Vacuum()
|
||||
{
|
||||
_database.Vacuum();
|
||||
|
||||
@@ -10,10 +10,12 @@ namespace NzbDrone.Core.Datastore
|
||||
public class MainDatabase : IMainDatabase
|
||||
{
|
||||
private readonly IDatabase _database;
|
||||
private readonly DatabaseType _databaseType;
|
||||
|
||||
public MainDatabase(IDatabase database)
|
||||
{
|
||||
_database = database;
|
||||
_databaseType = _database == null ? DatabaseType.SQLite : _database.DatabaseType;
|
||||
}
|
||||
|
||||
public IDbConnection OpenConnection()
|
||||
@@ -25,6 +27,8 @@ namespace NzbDrone.Core.Datastore
|
||||
|
||||
public int Migration => _database.Migration;
|
||||
|
||||
public DatabaseType DatabaseType => _databaseType;
|
||||
|
||||
public void Vacuum()
|
||||
{
|
||||
_database.Vacuum();
|
||||
|
||||
@@ -144,7 +144,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
.WithColumn("Items").AsString().NotNullable()
|
||||
.WithColumn("Language").AsInt32().Nullable();
|
||||
|
||||
Execute.Sql("UPDATE Profiles SET Language = 1");
|
||||
Execute.Sql("UPDATE \"Profiles\" SET \"Language\" = 1");
|
||||
|
||||
Create.TableForModel("SceneMappings")
|
||||
.WithColumn("TvdbId").AsInt32()
|
||||
@@ -243,8 +243,8 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
|
||||
Insert.IntoTable("DelayProfiles").Row(new
|
||||
{
|
||||
EnableUsenet = 1,
|
||||
EnableTorrent = 1,
|
||||
EnableUsenet = true,
|
||||
EnableTorrent = true,
|
||||
PreferredProtocol = 1,
|
||||
UsenetDelay = 0,
|
||||
TorrentDelay = 0,
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
protected override void MainDbUpgrade()
|
||||
{
|
||||
Alter.Table("ScheduledTasks").AlterColumn("Interval").AsDouble();
|
||||
Execute.Sql("UPDATE ScheduledTasks SET Interval=0.25 WHERE TypeName='NzbDrone.Core.Download.CheckForFinishedDownloadCommand'");
|
||||
Execute.Sql("UPDATE \"ScheduledTasks\" SET \"Interval\" = 0.25 WHERE \"TypeName\" = 'NzbDrone.Core.Download.CheckForFinishedDownloadCommand'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand namingConfigCmd = conn.CreateCommand())
|
||||
{
|
||||
namingConfigCmd.Transaction = tran;
|
||||
namingConfigCmd.CommandText = @"SELECT * FROM NamingConfig LIMIT 1";
|
||||
namingConfigCmd.CommandText = @"SELECT * FROM ""NamingConfig"" LIMIT 1";
|
||||
using (IDataReader namingConfigReader = namingConfigCmd.ExecuteReader())
|
||||
{
|
||||
while (namingConfigReader.Read())
|
||||
@@ -38,9 +38,9 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
var text = string.Format("UPDATE NamingConfig " +
|
||||
"SET StandardMovieFormat = '{0}', " +
|
||||
"MovieFolderFormat = '{1}'",
|
||||
var text = string.Format("UPDATE \"NamingConfig\" " +
|
||||
"SET \"StandardMovieFormat\" = '{0}', " +
|
||||
"\"MovieFolderFormat\" = '{1}'",
|
||||
standardMovieFormat,
|
||||
movieFolderFormat);
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Movies";
|
||||
getSeriesCmd.CommandText = @"SELECT ""Id"", ""Title"" FROM ""Movies""";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
@@ -31,7 +31,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET SortTitle = ? WHERE Id = ?";
|
||||
updateCmd.CommandText = "UPDATE \"Movies\" SET \"SortTitle\" = ? WHERE \"Id\" = ?";
|
||||
updateCmd.AddParameter(sortTitle);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title FROM Movies";
|
||||
getSeriesCmd.CommandText = @"SELECT ""Id"", ""Title"" FROM ""Movies""";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
@@ -30,7 +30,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET SortTitle = ? WHERE Id = ?";
|
||||
updateCmd.CommandText = "UPDATE \"Movies\" SET \"SortTitle\" = ? WHERE \"Id\" = ?";
|
||||
updateCmd.AddParameter(sortTitle);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, RelativePath FROM MovieFiles";
|
||||
getSeriesCmd.CommandText = @"SELECT ""Id"", ""RelativePath"" FROM ""MovieFiles""";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
@@ -39,7 +39,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE MovieFiles SET Edition = ? WHERE Id = ?";
|
||||
updateCmd.CommandText = "UPDATE \"MovieFiles\" SET \"Edition\" = ? WHERE \"Id\" = ?";
|
||||
updateCmd.AddParameter(edition);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand getSeriesCmd = conn.CreateCommand())
|
||||
{
|
||||
getSeriesCmd.Transaction = tran;
|
||||
getSeriesCmd.CommandText = @"SELECT Id, Title, Year, TmdbId FROM Movies";
|
||||
getSeriesCmd.CommandText = @"SELECT ""Id"", ""Title"", ""Year"", ""TmdbId"" FROM ""Movies""";
|
||||
using (IDataReader seriesReader = getSeriesCmd.ExecuteReader())
|
||||
{
|
||||
while (seriesReader.Read())
|
||||
@@ -32,7 +32,7 @@ namespace NzbDrone.Core.Datastore.Migration
|
||||
using (IDbCommand updateCmd = conn.CreateCommand())
|
||||
{
|
||||
updateCmd.Transaction = tran;
|
||||
updateCmd.CommandText = "UPDATE Movies SET TitleSlug = ? WHERE Id = ?";
|
||||
updateCmd.CommandText = "UPDATE \"Movies\" SET \"TitleSlug\" = ? WHERE \"Id\" = ?";
|
||||
updateCmd.AddParameter(titleSlug);
|
||||
updateCmd.AddParameter(id);
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user