From e36693c01c06e1c080a6dbd1317b7a7f8b4aa112 Mon Sep 17 00:00:00 2001 From: Ankit Agrawal Date: Fri, 10 Feb 2017 16:38:09 +0530 Subject: [PATCH] Removed metaClass mocks. #6 --- build.gradle | 2 +- .../fileuploader/BaseTestSetup.groovy | 10 + .../BaseFileUploaderServiceSpecSetup.groovy | 87 +++++--- .../fileuploader/FileGroupSpec.groovy | 43 ++++ .../FileUploaderServiceSpec.groovy | 210 ++++++++++-------- .../GoogleCDNFileUploaderImplSpec.groovy | 3 + 6 files changed, 227 insertions(+), 128 deletions(-) diff --git a/build.gradle b/build.gradle index bacdb5c..8cd7abe 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,7 @@ buildscript { } } -version "3.0.3" +version "3.0.4" group "com.causecode.plugins" apply plugin: "idea" diff --git a/src/main/groovy/com/causecode/fileuploader/BaseTestSetup.groovy b/src/main/groovy/com/causecode/fileuploader/BaseTestSetup.groovy index 237215b..064e0ed 100644 --- a/src/main/groovy/com/causecode/fileuploader/BaseTestSetup.groovy +++ b/src/main/groovy/com/causecode/fileuploader/BaseTestSetup.groovy @@ -7,6 +7,8 @@ */ package com.causecode.fileuploader +import org.apache.commons.fileupload.disk.DiskFileItem + /** * This class contains common setup that can be used in unit, functional and integration test cases. * @@ -22,4 +24,12 @@ trait BaseTestSetup { file.createNewFile() file << 'This is a test document.' } + + DiskFileItem getDiskFileItemInstance(File fileInstance) { + DiskFileItem fileItem = new DiskFileItem('file', 'text/plain', false, fileInstance.name, + (int) fileInstance.length() , fileInstance.parentFile) + fileItem.outputStream + + return fileItem + } } diff --git a/src/test/groovy/com/causecode/fileuploader/BaseFileUploaderServiceSpecSetup.groovy b/src/test/groovy/com/causecode/fileuploader/BaseFileUploaderServiceSpecSetup.groovy index fc3edc5..a6ce66b 100644 --- a/src/test/groovy/com/causecode/fileuploader/BaseFileUploaderServiceSpecSetup.groovy +++ b/src/test/groovy/com/causecode/fileuploader/BaseFileUploaderServiceSpecSetup.groovy @@ -10,7 +10,6 @@ package com.causecode.fileuploader import com.causecode.fileuploader.cdn.amazon.AmazonCDNFileUploaderImpl import com.causecode.fileuploader.cdn.google.GoogleCDNFileUploaderImpl import com.causecode.fileuploader.cdn.google.GoogleCredentials -import org.apache.commons.fileupload.disk.DiskFileItem import spock.lang.Specification /** @@ -19,43 +18,35 @@ import spock.lang.Specification */ class BaseFileUploaderServiceSpecSetup extends Specification implements BaseTestSetup { - void setup() { - GoogleCredentials.metaClass.getStorage = { -> - return - } + AmazonCDNFileUploaderImpl amazonCDNFileUploaderInstance - AmazonCDNFileUploaderImpl.metaClass.close = { -> - return true - } + GoogleCDNFileUploaderImpl googleCDNFileUploaderImplMock + AmazonCDNFileUploaderImpl amazonCDNFileUploaderImplMock + GoogleCredentials googleCredentialsMock + FileGroup fileGroupMock - GoogleCDNFileUploaderImpl.metaClass.close = { -> - return true - } + void setup() { + amazonCDNFileUploaderInstance = new AmazonCDNFileUploaderImpl() + googleCDNFileUploaderImplMock = GroovyMock(GoogleCDNFileUploaderImpl, global: true) + amazonCDNFileUploaderImplMock = GroovyMock(AmazonCDNFileUploaderImpl, global: true) + googleCredentialsMock = GroovyMock(GoogleCredentials, global: true) + fileGroupMock = GroovyMock(FileGroup, global: true) - Closure getTemporaryURL = { String containerName, String fileName, long expiration -> - return 'http://fixedURL.com' + googleCredentialsMock.storage >> { + return } - Closure uploadFile = { String containerName, File file, String fileName, boolean makePublic, long maxAge -> - return true + amazonCDNFileUploaderImplMock.close() >> { + return } - AmazonCDNFileUploaderImpl.metaClass.getTemporaryURL = getTemporaryURL - GoogleCDNFileUploaderImpl.metaClass.getTemporaryURL = getTemporaryURL - - AmazonCDNFileUploaderImpl.metaClass.uploadFile = uploadFile - GoogleCDNFileUploaderImpl.metaClass.uploadFile = uploadFile - } - - DiskFileItem getFileItem(File fileInstance) { - DiskFileItem fileItem = new DiskFileItem('file', 'text/plain', false, fileInstance.name, - (int) fileInstance.length() , fileInstance.parentFile) - fileItem.outputStream - return fileItem + googleCredentialsMock.close() >> { + return + } } void mockGetFileNameAndExtensions() { - FileGroup.metaClass.getFileNameAndExtensions = { def file, String customFileName -> + fileGroupMock.getFileNameAndExtensions(_, _) >> { return [fileName: 'test.txt', fileExtension: 'txt', customFileName: 'unit-test', empty: false, fileSize: 38L] } @@ -67,18 +58,48 @@ class BaseFileUploaderServiceSpecSetup extends Specification implements BaseTest } } + void mockFileDeleteMethod(boolean boolResult) { + File.metaClass.delete = { + return boolResult + } + } + boolean mockAuthenticateMethod() { - AmazonCDNFileUploaderImpl.metaClass.authenticate = { + new AmazonCDNFileUploaderImpl() >> amazonCDNFileUploaderImplMock + amazonCDNFileUploaderImplMock.authenticate() >> { return true } } void mockGetPermanentURL() { - Closure getPermanentURL = { String containerName, String fileName -> - return 'http://fixedURL.com' + amazonCDNFileUploaderImplMock.getPermanentURL(_, _) >> 'http://fixedURL.com' + googleCDNFileUploaderImplMock.getPermanentURL(_, _) >> 'http://fixedURL.com' + } + + void mockGetTemporaryURL() { + amazonCDNFileUploaderImplMock.getTemporaryURL(_, _, _) >> 'http://fixedURL.com' + googleCDNFileUploaderImplMock.getTemporaryURL(_, _, _) >> 'http://fixedURL.com' + amazonCDNFileUploaderImplMock.getPermanentURL(_, _) >> 'http://fixedURL.com' + googleCDNFileUploaderImplMock.getPermanentURL(_, _) >> 'http://fixedURL.com' + } + + void mockUploadFileMethod(boolean value) { + amazonCDNFileUploaderImplMock.uploadFile(_, _, _, _, _) >> value + googleCDNFileUploaderImplMock.uploadFile(_, _, _, _, _) >> value + } + + void mockGetProviderInstance(String provider) { + service.metaClass.getProviderInstance = { String providerName -> + provider == 'google' ? googleCDNFileUploaderImplMock : amazonCDNFileUploaderImplMock } + } + + void mockFileGroupConstructor(String storageTypes) { + new FileGroup(_) >> { String group -> + fileGroupMock.groupName = group + fileGroupMock.groupConfig >> [storageTypes: storageTypes] - AmazonCDNFileUploaderImpl.metaClass.getPermanentURL = getPermanentURL - GoogleCDNFileUploaderImpl.metaClass.getPermanentURL = getPermanentURL + return fileGroupMock + } } } diff --git a/src/test/groovy/com/causecode/fileuploader/FileGroupSpec.groovy b/src/test/groovy/com/causecode/fileuploader/FileGroupSpec.groovy index 6f2e094..af81933 100644 --- a/src/test/groovy/com/causecode/fileuploader/FileGroupSpec.groovy +++ b/src/test/groovy/com/causecode/fileuploader/FileGroupSpec.groovy @@ -10,8 +10,10 @@ package com.causecode.fileuploader import grails.buildtestdata.mixin.Build import grails.test.mixin.TestMixin import grails.test.mixin.support.GrailsUnitTestMixin +import org.apache.commons.fileupload.disk.DiskFileItem import org.springframework.context.MessageSource import org.springframework.context.i18n.LocaleContextHolder +import org.springframework.web.multipart.commons.CommonsMultipartFile import spock.lang.Specification /** @@ -124,4 +126,45 @@ class FileGroupSpec extends Specification implements BaseTestSetup { StorageConfigurationException e = thrown() e.message == 'file too big' } + + void "test getFileNameAndExtensions method when file belongs to CommonsMultipartFile class"() { + given: 'Instances of CommonsMultipartFile and FileGroup class' + File fileInstance = getFileInstance('./temp/test.txt') + DiskFileItem fileItem = getDiskFileItemInstance(fileInstance) + CommonsMultipartFile commonsMultipartFileInstance = new CommonsMultipartFile(fileItem) + + FileGroup fileGroupInstance = new FileGroup('testLocal') + + when: 'getFileNameAndExtensions method is called' + Map result = fileGroupInstance.getFileNameAndExtensions(commonsMultipartFileInstance, 'testLocal.txt') + + then: 'Method returns a valid map' + result.fileName == 'testLocal.txt' + result.customFileName == 'testLocal.txt' + result.empty == true + result.fileSize == 0L + + cleanup: + fileInstance.delete() + } + + void "test getCdnProvider method to return provider name"() { + given: 'An instance of FileGroup class' + FileGroup fileGroupInstance = new FileGroup('testGoogle') + + expect: 'Method to return correct CDn provider for this group' + fileGroupInstance.cdnProvider == CDNProvider.GOOGLE + } + + void "test getLocalSystemPath method to return localPath"() { + given: 'An instance of FileGroup class' + FileGroup fileGroupInstance = new FileGroup('testLocal') + Map fileProperties = [fileName: 'test', fileExtension: 'txt'] + + when: 'getLocalSystemPath method is called' + String localPath = fileGroupInstance.getLocalSystemPath('', fileProperties, 0L) + + then: 'Method returns a valid local path' + localPath == './temp/0/test.txt' + } } diff --git a/src/test/groovy/com/causecode/fileuploader/FileUploaderServiceSpec.groovy b/src/test/groovy/com/causecode/fileuploader/FileUploaderServiceSpec.groovy index a9a797f..7daf3c7 100644 --- a/src/test/groovy/com/causecode/fileuploader/FileUploaderServiceSpec.groovy +++ b/src/test/groovy/com/causecode/fileuploader/FileUploaderServiceSpec.groovy @@ -8,7 +8,6 @@ package com.causecode.fileuploader import com.causecode.fileuploader.cdn.amazon.AmazonCDNFileUploaderImpl -import com.causecode.fileuploader.cdn.google.GoogleCDNFileUploaderImpl import grails.buildtestdata.mixin.Build import grails.test.mixin.TestFor import grails.test.runtime.DirtiesRuntime @@ -21,15 +20,16 @@ import org.springframework.context.MessageSource import org.springframework.context.i18n.LocaleContextHolder import org.springframework.web.multipart.commons.CommonsMultipartFile import spock.lang.Unroll +import spock.util.mop.ConfineMetaClassChanges /** * This file contains unit test cases for FileUploaderService class. */ +@ConfineMetaClassChanges([FileUploaderService, File]) @TestFor(FileUploaderService) @Build([UFile, UFileMoveHistory]) class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { - @DirtiesRuntime void "test isPublicGroup for various file groups"() { mockCodec(HTMLCodec) @@ -40,17 +40,20 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { service.isPublicGroup() == false } - @DirtiesRuntime void "test moveFilesToCDN method for successfully moving a file"() { given: 'An instance of UFile and File' UFile uFileInstance = UFile.build() File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } + mockGetProviderInstance('google') + + mockUploadFileMethod(true) + when: 'moveFilesToCDN method is called' assert uFileInstance.provider == CDNProvider.GOOGLE service.moveFilesToCDN([uFileInstance], CDNProvider.AMAZON) @@ -82,6 +85,12 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { and: 'Mocked AmazonCDNFileUploaderImpl\'s methods' mockAuthenticateMethod() + mockGetTemporaryURL() + + and: 'Mocked getProviderInstance method' + service.metaClass.getProviderInstance = { String providerName -> + return amazonCDNFileUploaderInstance + } when: 'renewTemporaryURL method is called' service.renewTemporaryURL() @@ -91,7 +100,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { uFileInstance1.path == 'https://xyz/abc' uFileInstance2.path == 'https://xyz/abc' uFileInstance3.path == 'https://xyz/abc' - uFilePath == 'http://fixedURL.com' + uFilePath != 'https://xyz/abc' when: 'renewTemporaryURL method is called' uFileInstance4.path = 'https://xyz/abc' @@ -101,26 +110,33 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { service.renewTemporaryURL(true) then: 'It should renew the image path of all the Instance' - uFileInstance1.path == 'http://fixedURL.com' - uFileInstance2.path == 'http://fixedURL.com' - uFileInstance3.path == 'http://fixedURL.com' - uFileInstance4.path == 'http://fixedURL.com' + uFileInstance1.path != 'https://xyz/abc' + uFileInstance2.path != 'https://xyz/abc' + uFileInstance3.path != 'https://xyz/abc' + uFileInstance4.path != 'https://xyz/abc' } @Unroll - @DirtiesRuntime void "test saveFile for uploading files for CDNProvider #provider"() { given: 'A file instance' File file = getFileInstance('./temp/test.txt') and: 'Mocked method' mockAuthenticateMethod() + mockGetFileNameAndExtensions() + mockUploadFileMethod(true) + service.metaClass.getProviderInstance = { String providerName -> + providerName == 'GOOGLE' ? googleCDNFileUploaderImplMock : amazonCDNFileUploaderImplMock + } + + new FileGroup(_) >> fileGroupMock + fileGroupMock.cdnProvider >> provider + fileGroupMock.groupConfig >> [storageTypes: 'CDN'] when: 'The saveFile method is called' UFile ufileInstancefile = service.saveFile(fileGroup, file, 'test') then: 'UFile instance should be successfully saved' - ufileInstancefile.id ufileInstancefile.provider == provider ufileInstancefile.extension == 'txt' ufileInstancefile.container == 'causecode-test' @@ -134,16 +150,23 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { 'testGoogle' | CDNProvider.GOOGLE } - @DirtiesRuntime void "test saveFile method in FileUploaderService when file upload fails"() { given: 'A file instance and mocked method \'uploadFile\' of class GoogleCDNFileUploaderImpl' File file = getFileInstance('./temp/test.txt') - GoogleCDNFileUploaderImpl.metaClass.uploadFile = { + 1 * googleCDNFileUploaderImplMock.uploadFile(_, _, _, _, _) >> { String containerName, File fileToUpload, String fileName, boolean makePublic, long maxAge -> throw new UploadFailureException(fileName, containerName, new Throwable()) } + mockGetProviderInstance('google') + + and: 'Mocked FileGroup class method call' + new FileGroup(_) >> fileGroupMock + fileGroupMock.cdnProvider >> CDNProvider.GOOGLE + fileGroupMock.groupConfig >> [storageTypes: 'CDN'] + mockGetFileNameAndExtensions() + when: 'The saveFile() method is called' service.saveFile('testGoogle', file, 'test') @@ -155,14 +178,17 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { file.delete() } - @DirtiesRuntime void "test uploadFileToCloud method for successful execution"() { given: 'A file instance and mocked method \'uploadFile\' of class GoogleCDNFileUploaderImpl' File file = getFileInstance('./temp/test.txt') - FileGroup fileGroupInstance = new FileGroup('testGoogle') + fileGroupMock.groupName >> 'testGoogle' + FileGroup fileGroupInstance = fileGroupMock Holders.grailsApplication.config.fileuploader.groups.testGoogle.makePublic = true and: 'Mocked methods' + fileGroupMock.cdnProvider >> CDNProvider.GOOGLE + mockGetProviderInstance('google') + mockUploadFileMethod(true) mockGetPermanentURL() when: 'The uploadFileToCloud method is called' @@ -176,7 +202,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { file.delete() } - @DirtiesRuntime void "test moveFilesToCDN method for making a file public while moving and error occurs"() { given: 'An instance of UFile and File' UFile uFileInstance = UFile.build(type: UFileType.CDN_PUBLIC) @@ -184,7 +209,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { assert uFileInstance.type == UFileType.CDN_PUBLIC and: 'Mocked method' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } @@ -201,14 +226,15 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test moveFilesToCDN method for making a file public while moving and no error occurs"() { given: 'An instance of UFile and File' UFile uFileInstance = UFile.build() File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + mockGetProviderInstance('google') + mockUploadFileMethod(true) + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } @@ -226,14 +252,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test moveFilesToCDN method for failure cases"() { given: 'An instance of UFile and File' UFile uFileInstance = UFile.build(type: UFileType.LOCAL) File fileInstance = getFileInstance('./temp/test.txt') when: 'moveFilesToCDN method is called and file does not exist' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } mockExistMethod(false) @@ -247,10 +272,9 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test moveToNewCDN method for various cases"() { given: 'Mocked method' - FileUploaderService.metaClass.moveFilesToCDN = { List uFileList, CDNProvider toCDNProvider -> + service.metaClass.moveFilesToCDN = { List uFileList, CDNProvider toCDNProvider -> return } @@ -267,20 +291,21 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { result } - @DirtiesRuntime void "test updateAllUFileCacheHeader for various cases"() { - given: 'Mocked method' + given: 'An instance of UFile and Mocked method' + UFile uFileInstance = UFile.build() mockAuthenticateMethod() - UFile.metaClass.static.withCriteria = { Closure closure -> + GroovyMock(UFile, global: true) + UFile.withCriteria(_) >> { Closure closure -> assert closure != null new JsonBuilder() closure - return UFile.build() + return uFileInstance } - AmazonCDNFileUploaderImpl.metaClass.updatePreviousFileMetaData = { String containerName, String fileName, - Boolean makePublic, long maxAge -> - return } + amazonCDNFileUploaderImplMock.updatePreviousFileMetaData(_, _, _, _) >> { + return + } when: 'updateAllUFileCacheHeader method is called and provider is not AMAZON' def result = service.updateAllUFileCacheHeader(CDNProvider.GOOGLE) @@ -295,7 +320,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { noExceptionThrown() } - @DirtiesRuntime void "test getFileFromURL method to return a file"() { when: 'getFileFromURL method is called' File responseFile = service.getFileFromURL('http://causecode.com/test', 'test') @@ -304,14 +328,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { responseFile != null } - @DirtiesRuntime void "test cloneFile method for various cases"() { given: 'An instance of UFile and File' UFile ufIleInstance = UFile.build(name: 'test-file-1') File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - FileUploaderService.metaClass.saveFile = { String group, def file, String customFileName = '', + service.metaClass.saveFile = { String group, def file, String customFileName = '', Object userInstance = null, Locale locale = null -> return ufIleInstance } @@ -333,14 +356,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test cloneFile method for LOCAL type file"() { given: 'An instance of UFile and File' UFile ufIleInstance = UFile.build(name: 'test-file-1', path: 'http://unittest.com/test') File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - FileUploaderService.metaClass.saveFile = { String group, def file, String customFileName = '', + service.metaClass.saveFile = { String group, def file, String customFileName = '', Object userInstance = null, Locale locale = null -> return ufIleInstance } @@ -348,7 +370,9 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { when: 'cloneFile method is called for valid parameters and UFile is not LOCAL type' ufIleInstance.type = UFileType.CDN_PUBLIC - UrlValidator.metaClass.isValid = { String value -> + UrlValidator urlValidatorMock = GroovyMock(UrlValidator, global: true) + new UrlValidator() >> urlValidatorMock + urlValidatorMock.isValid(_) >> { return true } @@ -361,7 +385,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test resolvePath for various cases"() { given: 'An instance of UFile' UFile uFileInstance = UFile.build() @@ -387,14 +410,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { result == uFileInstance.path } - @DirtiesRuntime void "test fileForUFile method when UFile is public type"() { given: 'An instance of File and UFile' File fileInstance = getFileInstance('./temp/test.txt') UFile uFileInstance = UFile.build() and: 'Mocked methods' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } @@ -413,16 +435,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test deleteFileForUFile method for various cases"() { given: 'A UFile instance' UFile uFileInstance = UFile.build(type: UFileType.LOCAL) File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - File.metaClass.delete = { - return false - } + mockFileDeleteMethod(false) when: 'deleteFileForUFile method is called and file does not exist' mockExistMethod(false) @@ -443,23 +462,15 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test deleteFileForUFile method for PUBLIC file"() { given: 'A UFile instance' UFile uFileInstance = UFile.build(type: UFileType.CDN_PUBLIC) assert uFileInstance.type == UFileType.CDN_PUBLIC and: 'Mocked method' - GoogleCDNFileUploaderImpl.metaClass.deleteFile = { String containerName, String fileName -> + googleCDNFileUploaderImplMock.deleteFile(_, _) >> { } - when: 'deleteFileForUFile method is called and method executes successfully' - def response = service.deleteFileForUFile(uFileInstance) - - then: 'Method returns true and no exceptions are thrown' - noExceptionThrown() - response - when: 'deleteFileForUFile method is called and class does not exist' uFileInstance.provider = CDNProvider.RACKSPACE service.deleteFileForUFile(uFileInstance) @@ -467,9 +478,17 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { then: 'Method returns true and no exceptions are thrown' ProviderNotFoundException e = thrown() e.message == 'Provider RACKSPACE not found.' + + when: 'deleteFileForUFile method is called and method executes successfully' + uFileInstance.provider = CDNProvider.GOOGLE + mockGetProviderInstance('google') + def response = service.deleteFileForUFile(uFileInstance) + + then: 'Method returns true and no exceptions are thrown' + noExceptionThrown() + response } - @DirtiesRuntime // Note: Creating test file for testing delete method call. @SuppressWarnings(['JavaIoPackageAccess']) void "test deleteFileForUFile method for LOCAL file"() { @@ -479,9 +498,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { and: 'Mocked method' mockExistMethod(true) - File.metaClass.delete = { - return true - } + mockFileDeleteMethod(true) when: 'deleteFileForUFile method is called and method executes successfully' service.deleteFileForUFile(uFileInstance) @@ -490,16 +507,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { noExceptionThrown() } - @DirtiesRuntime void "test deleteFileForUFile method for LOCAL file when parent folder not empty"() { given: 'A UFile and a File instance' UFile uFileInstance = UFile.build(type: UFileType.LOCAL) and: 'Mocked method' mockExistMethod(true) - File.metaClass.delete = { - return true - } + mockFileDeleteMethod(true) when: 'deleteFileForUFile method is called and method executes successfully' service.deleteFileForUFile(uFileInstance) @@ -508,7 +522,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { noExceptionThrown() } - @DirtiesRuntime void "test deleteFile method for various cases"() { given: 'An instance of UFile' UFile uFileInstance = UFile.build(type: UFileType.LOCAL) @@ -529,10 +542,9 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { result } - @DirtiesRuntime void "test renewTemporaryURL method when fileUploaderInstance is null"() { given: 'Mocked method' - FileUploaderService.metaClass.getProviderInstance = { String name -> + service.metaClass.getProviderInstance = { String name -> return null } when: 'renewTemporaryURL method is called' @@ -542,7 +554,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { result == null } - @DirtiesRuntime void "test getProviderInstance method"() { when: 'getProviderInstance method is called and class does not exist' service.getProviderInstance('test') @@ -552,55 +563,70 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { e.message == 'Provider test not found.' when: 'getProviderInstance method is called and class exist' - def result = service.getProviderInstance('Amazon') + service.getProviderInstance('Amazon') then: 'No exception is thrown' noExceptionThrown() - result != null } - @DirtiesRuntime void "test saveFile method for various cases"() { given: 'An instance of File' File fileInstance = getFileInstance('./temp/test.txt') - DiskFileItem fileItem = getFileItem(fileInstance) + DiskFileItem fileItem = getDiskFileItemInstance(fileInstance) CommonsMultipartFile commonsMultipartFileInstance = new CommonsMultipartFile(fileItem) and: 'Mocked methods' + mockFileGroupConstructor('CDN') mockAuthenticateMethod() mockExistMethod(false) - - when: 'saveFile method is hit' - def result = service.saveFile('testGoogle', commonsMultipartFileInstance, 'test') - - then: 'Method should return null' - result == null + mockGetFileNameAndExtensions() + mockUploadFileMethod(true) + mockGetProviderInstance('google') + 3 * fileGroupMock.cdnProvider >> { + return + } >> { + return CDNProvider.GOOGLE + } when: 'saveFile is called and provider is not specified' mockGetFileNameAndExtensions() - FileGroup.metaClass.getCdnProvider = { return null } - service.saveFile('testGoogle', commonsMultipartFileInstance, 'test') then: 'Method should throw StorageConfigurationException' StorageConfigurationException e = thrown() e.message == 'Provider not defined in the Config. Please define one.' + when: 'saveFile method is hit' + mockUploadFileMethod(true) + def result = service.saveFile('testGoogle', commonsMultipartFileInstance, 'test') + + then: 'Method should return instance of UFile' + result.fileGroup == 'testGoogle' + result.type == UFileType.CDN_PUBLIC + cleanup: fileInstance.delete() } - @DirtiesRuntime void "test saveFile when provider is LOCAL"() { given: 'File instance' File fileInstance = getFileInstance('./temp/test.txt') - DiskFileItem fileItem = getFileItem(fileInstance) + DiskFileItem fileItem = getDiskFileItemInstance(fileInstance) CommonsMultipartFile commonsMultipartFileInstance = new CommonsMultipartFile(fileItem) and: 'Mocked methods' - mockGetFileNameAndExtensions() + mockFileGroupConstructor('LOCAL') + 2 * fileGroupMock.getFileNameAndExtensions(_, _) >> { + return [fileName: 'test.txt', fileExtension: 'txt', customFileName: 'unit-test', empty: false, + fileSize: 38L] + } >> { + return [fileName: null, fileExtension: 'txt', customFileName: 'unit-test', empty: false, + fileSize: 38L] + } + + 2 * fileGroupMock.getLocalSystemPath(_, _, _) >> './temp/newDir' when: 'saveFile method is called and file gets saved' def result = service.saveFile('testLocal', fileInstance, 'test') @@ -608,11 +634,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { then: 'Method should return saved UFile instance' result.id != null - when: 'saveFile method is called and error occures while saving file' - FileGroup.metaClass.getFileNameAndExtensions = { def file, String customFileName -> - return [fileName: null, fileExtension: 'txt', customFileName: 'unit-test', empty: false, - fileSize: 38L] - } + when: 'saveFile method is called and error occurs while saving file' result = service.saveFile('testLocal', commonsMultipartFileInstance, 'test') then: 'File would not be saved' @@ -622,13 +644,12 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test moveFailedFilesToCDN for various cases"() { given: 'Instances of UFileMoveHistory' UFileMoveHistory uFileMoveHistoryInstance = UFileMoveHistory.build(fromCDN: CDNProvider.RACKSPACE, toCDN: CDNProvider.GOOGLE, status: MoveStatus.FAILURE, ufile: UFile.build()) - FileUploaderService.metaClass.moveFilesToCDN = { List uFileList, CDNProvider toCDNProvider, + service.metaClass.moveFilesToCDN = { List uFileList, CDNProvider toCDNProvider, boolean makePublic = false -> return } @@ -640,7 +661,8 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { noExceptionThrown() when: 'moveFailedFilesToCDN method is called and failedList containes UFiles' - UFileMoveHistory.metaClass.static.withCriteria = { Closure closure -> + GroovyMock(UFileMoveHistory, global: true) + UFileMoveHistory.withCriteria(_) >> { Closure closure -> assert closure != null new JsonBuilder() closure return [uFileMoveHistoryInstance] @@ -652,7 +674,6 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { noExceptionThrown() } - @DirtiesRuntime void "test ufileById method for various cases"() { given: 'An instance of UFile' UFile uFileInstance = UFile.build(type: UFileType.LOCAL) @@ -677,14 +698,13 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { e.message == 'File not found' } - @DirtiesRuntime void "test fileForUFile method when file does not exist"() { given: 'An instance of File and UFile' File fileInstance = getFileInstance('./temp/test.txt') UFile uFileInstance = UFile.build(type: UFileType.LOCAL) and: 'Mocked methods' - FileUploaderService.metaClass.getFileFromURL = { String url, String filename -> + service.metaClass.getFileFromURL = { String url, String filename -> return fileInstance } @@ -707,17 +727,19 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { fileInstance.delete() } - @DirtiesRuntime void "test saveFile method when validation fails"() { given: 'An instance of File' File fileInstance = getFileInstance('./temp/test.txt') and: 'Mocked method' - FileGroup.metaClass.scopeFileName = { Object userInstance, Map fileDataMap, String group, - Long currentTimeMillis -> + fileGroupMock.scopeFileName(_, _, _, _) >> { throw new StorageConfigurationException('Container name not defined in the Config. Please define one.') } + mockGetFileNameAndExtensions() + mockFileGroupConstructor() + fileGroupMock.groupConfig >> [storageTypes: 'CDN'] + when: 'saveFile methods is called and exception is thrown while modifying fileName' service.saveFile('testGoogle', fileInstance) @@ -726,7 +748,7 @@ class FileUploaderServiceSpec extends BaseFileUploaderServiceSpecSetup { e.message == 'Container name not defined in the Config. Please define one.' when: 'saveFile method is called and FileSize is greater than permitted value' - FileGroup.metaClass.validateFileSize = { Map fileDataMap, Locale locale -> + fileGroupMock.validateFileSize(_, _) >> { throw new StorageConfigurationException('File too big.') } service.saveFile('testGoogle', fileInstance) diff --git a/src/test/groovy/com/causecode/fileuploader/cdn/google/GoogleCDNFileUploaderImplSpec.groovy b/src/test/groovy/com/causecode/fileuploader/cdn/google/GoogleCDNFileUploaderImplSpec.groovy index 0159eff..16b7eb1 100644 --- a/src/test/groovy/com/causecode/fileuploader/cdn/google/GoogleCDNFileUploaderImplSpec.groovy +++ b/src/test/groovy/com/causecode/fileuploader/cdn/google/GoogleCDNFileUploaderImplSpec.groovy @@ -14,6 +14,7 @@ import com.google.cloud.storage.Storage import com.google.cloud.storage.StorageException import com.causecode.fileuploader.GoogleStorageException import com.causecode.fileuploader.UploadFailureException +import grails.test.runtime.DirtiesRuntime import spock.lang.Specification /** @@ -81,6 +82,7 @@ class GoogleCDNFileUploaderImplSpec extends Specification { noExceptionThrown() } + @DirtiesRuntime void "test Google Cloud Storage for delete failure"() { given: 'mocked methods for Blob class' mockGetBlobMethod() @@ -94,6 +96,7 @@ class GoogleCDNFileUploaderImplSpec extends Specification { e.message == 'Could not delete file testFile from container dummyContainer' } + @DirtiesRuntime void "test Google Cloud Storage for successful deletion"() { given: 'mocked method for Blob class' mockGetBlobMethod()