diff --git a/spec/FilesControllerTestFactory.js b/spec/FilesControllerTestFactory.js index 217a383a..b467d031 100644 --- a/spec/FilesControllerTestFactory.js +++ b/spec/FilesControllerTestFactory.js @@ -1,35 +1,34 @@ - var FilesController = require('../src/Controllers/FilesController').FilesController; var Config = require("../src/Config"); var testAdapter = function(name, adapter) { // Small additional tests to improve overall coverage - + var config = new Config(Parse.applicationId); var filesController = new FilesController(adapter); describe("FilesController with "+name,()=>{ - + it("should properly expand objects", (done) => { - + var result = filesController.expandFilesInObject(config, function(){}); - + expect(result).toBeUndefined(); - + var fullFile = { type: '__type', url: "http://an.url" } - + var anObject = { aFile: fullFile } filesController.expandFilesInObject(config, anObject); expect(anObject.aFile.url).toEqual("http://an.url"); - + done(); - }) - + }) + it("should properly create, read, delete files", (done) => { var filename; filesController.createFile(config, "file.txt", "hello world").then( (result) => { @@ -51,14 +50,14 @@ var testAdapter = function(name, adapter) { console.error(err); done(); }).then((result) => { - + filesController.getFileData(config, filename).then((res) => { fail("the file should be deleted"); done(); }, (err) => { - done(); + done(); }); - + }, (err) => { fail("The adapter should delete the file"); console.error(err); diff --git a/src/Adapters/AdapterLoader.js b/src/Adapters/AdapterLoader.js index a9521f0b..654948e9 100644 --- a/src/Adapters/AdapterLoader.js +++ b/src/Adapters/AdapterLoader.js @@ -1,6 +1,5 @@ export function loadAdapter(adapter, defaultAdapter, options) { - - if (!adapter) + if (!adapter) { if (!defaultAdapter) { return options; @@ -20,7 +19,7 @@ export function loadAdapter(adapter, defaultAdapter, options) { if (adapter.default) { adapter = adapter.default; } - + return loadAdapter(adapter, undefined, options); } else if (adapter.module) { return loadAdapter(adapter.module, undefined, adapter.options); @@ -30,7 +29,7 @@ export function loadAdapter(adapter, defaultAdapter, options) { return loadAdapter(adapter.adapter, undefined, adapter.options); } // return the adapter as provided - return adapter; + return adapter; } export default loadAdapter; diff --git a/src/Adapters/Files/GCSAdapter.js b/src/Adapters/Files/GCSAdapter.js index e749502d..065592eb 100644 --- a/src/Adapters/Files/GCSAdapter.js +++ b/src/Adapters/Files/GCSAdapter.js @@ -4,18 +4,33 @@ import { storage } from 'gcloud'; import { FilesAdapter } from './FilesAdapter'; import requiredParameter from '../../requiredParameter'; +function requiredOrFromEnvironment(env, name) { + let environmentVariable = process.env[env]; + if (!environmentVariable) { + requiredParameter(`GCSAdapter requires an ${name}`); + } + return environmentVariable; +} + +function fromEnvironmentOrDefault(env, defaultValue) { + let environmentVariable = process.env[env]; + if (environmentVariable) { + return environmentVariable; + } + return defaultValue; +} + export class GCSAdapter extends FilesAdapter { // GCS Project ID and the name of a corresponding Keyfile are required. // Unlike the S3 adapter, you must create a new Cloud Storage bucket, as this is not created automatically. // See https://googlecloudplatform.github.io/gcloud-node/#/docs/master/guides/authentication // for more details. constructor( - projectId = requiredParameter('GCSAdapter requires a GCP Project ID'), - keyFilename = requiredParameter('GCSAdapter requires a GCP keyfile'), - bucket = requiredParameter('GCSAdapter requires a GCS bucket name'), - { bucketPrefix = '', - directAccess = false } = {} - ) { + projectId = requiredOrFromEnvironment('GCP_PROJECT_ID', 'projectId'), + keyFilename = requiredOrFromEnvironment('GCP_KEYFILE_PATH', 'keyfile path'), + bucket = requiredOrFromEnvironment('GCS_BUCKET_NAME', 'bucket name'), + { bucketPrefix = fromEnvironmentOrDefault('GCS_BUCKET_PREFIX', ''), + directAccess = fromEnvironmentOrDefault('GCS_DIRECT_ACCESS', false) } = {}) { super(); this._bucket = bucket; diff --git a/src/Controllers/AdaptableController.js b/src/Controllers/AdaptableController.js index ab7d7156..7ff8ce29 100644 --- a/src/Controllers/AdaptableController.js +++ b/src/Controllers/AdaptableController.js @@ -2,7 +2,7 @@ AdaptableController.js AdaptableController is the base class for all controllers -that support adapter, +that support adapter, The super class takes care of creating the right instance for the adapter based on the parameters passed @@ -28,30 +28,30 @@ export class AdaptableController { this.validateAdapter(adapter); this[_adapter] = adapter; } - + get adapter() { return this[_adapter]; } - + get config() { return new Config(this.appId); } - + expectedAdapterType() { throw new Error("Subclasses should implement expectedAdapterType()"); } - + validateAdapter(adapter) { if (!adapter) { throw new Error(this.constructor.name+" requires an adapter"); } - + let Type = this.expectedAdapterType(); // Allow skipping for testing - if (!Type) { + if (!Type) { return; } - + // Makes sure the prototype matches let mismatches = Object.getOwnPropertyNames(Type.prototype).reduce( (obj, key) => { const adapterType = typeof adapter[key]; @@ -64,7 +64,7 @@ export class AdaptableController { } return obj; }, {}); - + if (Object.keys(mismatches).length > 0) { throw new Error("Adapter prototype don't match expected prototype", adapter, mismatches); } diff --git a/src/Controllers/FilesController.js b/src/Controllers/FilesController.js index 712e326c..9abd87ff 100644 --- a/src/Controllers/FilesController.js +++ b/src/Controllers/FilesController.js @@ -13,11 +13,11 @@ export class FilesController extends AdaptableController { } createFile(config, filename, data, contentType) { - + let extname = path.extname(filename); - + const hasExtension = extname.length > 0; - + if (!hasExtension && contentType && mime.extension(contentType)) { filename = filename + '.' + mime.extension(contentType); } else if (hasExtension && !contentType) { @@ -27,6 +27,8 @@ export class FilesController extends AdaptableController { filename = randomHexString(32) + '_' + filename; var location = this.adapter.getFileLocation(config, filename); + console.log(this.adapter); + console.log(location); return this.adapter.createFile(config, filename, data, contentType).then(() => { return Promise.resolve({ url: location,