Skip to content

Commit

Permalink
Add Storage Integration tests (#3414)
Browse files Browse the repository at this point in the history
  • Loading branch information
schmidt-sebastian authored Jul 17, 2020
1 parent ea699fa commit ee33ebf
Show file tree
Hide file tree
Showing 14 changed files with 233 additions and 66 deletions.
5 changes: 5 additions & 0 deletions .changeset/strange-lions-dress.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@firebase/storage": patch
---

Error messages for backend errors now include the backend's reponse message.
17 changes: 13 additions & 4 deletions packages/storage/karma.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
const karma = require('karma');
const path = require('path');
const karmaBase = require('../../config/karma.base');

const files = [`test/**/*`];
const { argv } = require('yargs');

module.exports = function (config) {
const karmaConfig = Object.assign({}, karmaBase, {
// files to load into karma
files: files,
files: getTestFiles(argv),
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['mocha']
Expand All @@ -33,4 +32,14 @@ module.exports = function (config) {
config.set(karmaConfig);
};

module.exports.files = files;
function getTestFiles(argv) {
if (argv.unit) {
return ['test/unit/*'];
} else if (argv.integration) {
return ['test/integration/*'];
} else {
return ['test/**/*'];
}
}

module.exports.files = getTestFiles(argv);
3 changes: 3 additions & 0 deletions packages/storage/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
"dev": "rollup -c -w",
"test": "run-p test:browser lint",
"test:ci": "node ../../scripts/run_tests_in_ci.js",
"test:browser:unit": "karma start --single-run --unit",
"test:browser:integration": "karma start --single-run --integration",
"test:browser": "karma start --single-run",
"prepare": "yarn build",
"prettier": "prettier --write 'src/**/*.ts' 'test/**/*.ts'"
Expand All @@ -31,6 +33,7 @@
"@firebase/app-types": "0.x"
},
"devDependencies": {
"@firebase/auth": "0.x",
"rollup": "2.21.0",
"rollup-plugin-typescript2": "0.27.1",
"typescript": "3.9.6"
Expand Down
6 changes: 5 additions & 1 deletion packages/storage/src/implementation/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ export class FirebaseStorageError implements Error {
}

get message(): string {
return this.message_;
if (this.serverResponse_) {
return this.message_ + '\n' + this.serverResponse_;
} else {
return this.message_;
}
}

get serverResponse(): null | string {
Expand Down
145 changes: 145 additions & 0 deletions packages/storage/test/integration/integration.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
/**
* @license
* Copyright 2020 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import firebase from '@firebase/app';
import '@firebase/auth';

// See https://github.com/typescript-eslint/typescript-eslint/issues/363
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import * as storage from '@firebase/storage-types';

import { expect } from 'chai';
import '../../index';

// eslint-disable-next-line @typescript-eslint/no-require-imports
const PROJECT_CONFIG = require('../../../../config/project.json');

export const PROJECT_ID = PROJECT_CONFIG.projectId;
export const STORAGE_BUCKET = PROJECT_CONFIG.storageBucket;
export const API_KEY = PROJECT_CONFIG.apiKey;

let appCount = 0;

export async function withTestInstance(
fn: (storage: storage.FirebaseStorage) => void | Promise<void>
): Promise<void> {
const app = firebase.initializeApp(
{ apiKey: API_KEY, projectId: PROJECT_ID, storageBucket: STORAGE_BUCKET },
'test-app-' + appCount++
);
await firebase.auth!(app).signInAnonymously();
const storage = firebase.storage!(app);
return fn(storage);
}

describe('FirebaseStorage', () => {
it('can upload bytes', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/bytes');
await ref.put(new Uint8Array([0, 1, 3]));
});
});

it('can upload string', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/string');
await ref.putString('foo');
});
});

it('validates operations on root', () => {
return withTestInstance(async storage => {
const ref = storage.ref('');
try {
// eslint-disable-next-line @typescript-eslint/no-floating-promises
ref.putString('foo');
expect.fail();
} catch (e) {
expect(e.message).to.satisfy((v: string) =>
v.match(
/The operation 'putString' cannot be performed on a root reference/
)
);
}
});
});

it('can delete object ', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/delete');
await ref.putString('foo');

// getDownloadURL() succeeds for an existing object
await ref.getDownloadURL();

await ref.delete();
try {
// getDownloadURL() fails for a deleted object
await ref.getDownloadURL();
expect.fail();
} catch (e) {
expect(e.message).to.satisfy((v: string) =>
v.match(/Object 'public\/delete' does not exist/)
);
}
});
});

it('can get download URL', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/downloadurl');
await ref.put(new Uint8Array([0, 1, 3]));
const url = await ref.getDownloadURL();
expect(url).to.satisfy((v: string) =>
v.match(
/https:\/\/firebasestorage\.googleapis\.com\/v0\/b\/.*\/o\/public%2Fdownloadurl/
)
);
});
});

it('can get metadata', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/getmetadata');
await ref.put(new Uint8Array([0, 1, 3]));
const metadata = await ref.getMetadata();
expect(metadata.name).to.equal('getmetadata');
});
});

it('can update metadata', () => {
return withTestInstance(async storage => {
const ref = storage.ref('public/updatemetadata');
await ref.put(new Uint8Array([0, 1, 3]));
const metadata = await ref.updateMetadata({
customMetadata: { foo: 'bar' }
});
expect(metadata.customMetadata).to.deep.equal({ foo: 'bar' });
});
});

it('can list files', () => {
return withTestInstance(async storage => {
await storage.ref('public/list/a').putString('');
await storage.ref('public/list/b').putString('');
await storage.ref('public/list/c/d').putString('');
const listResult = await storage.ref('public/list').listAll();
expect(listResult.items.map(v => v.name)).to.have.members(['a', 'b']);
expect(listResult.prefixes.map(v => v.name)).to.have.members(['c']);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@

import { assert } from 'chai';
import * as sinon from 'sinon';
import { FbsBlob } from '../src/implementation/blob';
import * as type from '../src/implementation/type';
import { FbsBlob } from '../../src/implementation/blob';
import * as type from '../../src/implementation/type';
import * as testShared from './testshared';

describe('Firebase Storage > Blob', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,22 @@
*/
import { assert } from 'chai';
import { FirebaseApp } from '@firebase/app-types';
import { AuthWrapper } from '../src/implementation/authwrapper';
import { makeRequest } from '../src/implementation/request';
import { StringFormat } from '../src/implementation/string';
import { Headers } from '../src/implementation/xhrio';
import { Metadata } from '../src/metadata';
import { Reference } from '../src/reference';
import { Service } from '../src/service';
import { AuthWrapper } from '../../src/implementation/authwrapper';
import { makeRequest } from '../../src/implementation/request';
import { StringFormat } from '../../src/implementation/string';
import { Headers } from '../../src/implementation/xhrio';
import { Metadata } from '../../src/metadata';
import { Reference } from '../../src/reference';
import { Service } from '../../src/service';
import * as testShared from './testshared';
import { SendHook, TestingXhrIo } from './xhrio';
import { DEFAULT_HOST } from '../src/implementation/constants';
import { FirebaseAuthInternal } from '@firebase/auth-interop-types';
import { DEFAULT_HOST } from '../../src/implementation/constants';
import { Provider } from '@firebase/component';

/* eslint-disable @typescript-eslint/no-floating-promises */
function makeFakeService(
app: FirebaseApp,
authProvider: Provider<FirebaseAuthInternal>,
authProvider: Provider<'auth-internal'>,
sendHook: SendHook
): Service {
return new Service(app, authProvider, testShared.makePool(sendHook));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
import { assert } from 'chai';
import * as sinon from 'sinon';
import firebase from '@firebase/app';
import { makeRequest } from '../src/implementation/request';
import { RequestInfo } from '../src/implementation/requestinfo';
import { XhrIo } from '../src/implementation/xhrio';
import { makeRequest } from '../../src/implementation/request';
import { RequestInfo } from '../../src/implementation/requestinfo';
import { XhrIo } from '../../src/implementation/xhrio';
import { makePool } from './testshared';
import { TestingXhrIo } from './xhrio';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
* limitations under the License.
*/
import { assert } from 'chai';
import { AuthWrapper } from '../src/implementation/authwrapper';
import { FbsBlob } from '../src/implementation/blob';
import { Location } from '../src/implementation/location';
import * as MetadataUtils from '../src/implementation/metadata';
import { makeRequest } from '../src/implementation/request';
import * as requests from '../src/implementation/requests';
import { makeUrl } from '../src/implementation/url';
import * as errors from '../src/implementation/error';
import { RequestInfo } from '../src/implementation/requestinfo';
import { XhrIoPool } from '../src/implementation/xhriopool';
import { Metadata } from '../src/metadata';
import { Reference } from '../src/reference';
import { Service } from '../src/service';
import { AuthWrapper } from '../../src/implementation/authwrapper';
import { FbsBlob } from '../../src/implementation/blob';
import { Location } from '../../src/implementation/location';
import * as MetadataUtils from '../../src/implementation/metadata';
import { makeRequest } from '../../src/implementation/request';
import * as requests from '../../src/implementation/requests';
import { makeUrl } from '../../src/implementation/url';
import * as errors from '../../src/implementation/error';
import { RequestInfo } from '../../src/implementation/requestinfo';
import { XhrIoPool } from '../../src/implementation/xhriopool';
import { Metadata } from '../../src/metadata';
import { Reference } from '../../src/reference';
import { Service } from '../../src/service';
import {
assertObjectIncludes,
fakeXhrIo,
Expand All @@ -36,7 +36,7 @@ import {
import {
DEFAULT_HOST,
CONFIG_STORAGE_BUCKET_KEY
} from '../src/implementation/constants';
} from '../../src/implementation/constants';
import { FirebaseApp } from '@firebase/app-types';

describe('Firebase Storage > Requests', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
* limitations under the License.
*/
import { assert } from 'chai';
import { TaskEvent } from '../src/implementation/taskenums';
import { XhrIoPool } from '../src/implementation/xhriopool';
import { Service } from '../src/service';
import { TaskEvent } from '../../src/implementation/taskenums';
import { XhrIoPool } from '../../src/implementation/xhriopool';
import { Service } from '../../src/service';
import * as testShared from './testshared';
import { DEFAULT_HOST } from '../src/implementation/constants';
import { FirebaseStorageError } from '../src/implementation/error';
import { DEFAULT_HOST } from '../../src/implementation/constants';
import { FirebaseStorageError } from '../../src/implementation/error';

const fakeAppGs = testShared.makeFakeApp('gs://mybucket');
const fakeAppGsEndingSlash = testShared.makeFakeApp('gs://mybucket/');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* limitations under the License.
*/
import { assert } from 'chai';
import { dataFromString, StringFormat } from '../src/implementation/string';
import { dataFromString, StringFormat } from '../../src/implementation/string';
import { assertThrows, assertUint8ArrayEquals } from './testshared';

describe('Firebase Storage > String', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,17 @@
* limitations under the License.
*/
import { assert } from 'chai';
import { AuthWrapper } from '../src/implementation/authwrapper';
import { FbsBlob } from '../src/implementation/blob';
import { Location } from '../src/implementation/location';
import { getMappings } from '../src/implementation/metadata';
import { Unsubscribe } from '../src/implementation/observer';
import { makeRequest } from '../src/implementation/request';
import { TaskEvent, TaskState } from '../src/implementation/taskenums';
import { Headers } from '../src/implementation/xhrio';
import { Reference } from '../src/reference';
import { Service } from '../src/service';
import { UploadTask } from '../src/task';
import { AuthWrapper } from '../../src/implementation/authwrapper';
import { FbsBlob } from '../../src/implementation/blob';
import { Location } from '../../src/implementation/location';
import { getMappings } from '../../src/implementation/metadata';
import { Unsubscribe } from '../../src/implementation/observer';
import { makeRequest } from '../../src/implementation/request';
import { TaskEvent, TaskState } from '../../src/implementation/taskenums';
import { Headers } from '../../src/implementation/xhrio';
import { Reference } from '../../src/reference';
import { Service } from '../../src/service';
import { UploadTask } from '../../src/task';
import {
assertThrows,
bind as fbsBind,
Expand Down
Loading

0 comments on commit ee33ebf

Please sign in to comment.