ci: Find duplicate and slow tests (#9188)
This commit is contained in:
@@ -141,35 +141,6 @@ describe('Auth', () => {
|
||||
expect(userAuth.user.id).toBe(user.id);
|
||||
});
|
||||
|
||||
it('should load auth without a config', async () => {
|
||||
const user = new Parse.User();
|
||||
await user.signUp({
|
||||
username: 'hello',
|
||||
password: 'password',
|
||||
});
|
||||
expect(user.getSessionToken()).not.toBeUndefined();
|
||||
const userAuth = await getAuthForSessionToken({
|
||||
sessionToken: user.getSessionToken(),
|
||||
});
|
||||
expect(userAuth.user instanceof Parse.User).toBe(true);
|
||||
expect(userAuth.user.id).toBe(user.id);
|
||||
});
|
||||
|
||||
it('should load auth with a config', async () => {
|
||||
const user = new Parse.User();
|
||||
await user.signUp({
|
||||
username: 'hello',
|
||||
password: 'password',
|
||||
});
|
||||
expect(user.getSessionToken()).not.toBeUndefined();
|
||||
const userAuth = await getAuthForSessionToken({
|
||||
sessionToken: user.getSessionToken(),
|
||||
config: Config.get('test'),
|
||||
});
|
||||
expect(userAuth.user instanceof Parse.User).toBe(true);
|
||||
expect(userAuth.user.id).toBe(user.id);
|
||||
});
|
||||
|
||||
describe('getRolesForUser', () => {
|
||||
const rolesNumber = 100;
|
||||
|
||||
|
||||
@@ -469,29 +469,6 @@ describe('AuthenticationProviders', function () {
|
||||
expect(providerOptions).toEqual(options.facebook);
|
||||
});
|
||||
|
||||
it('should throw error when Facebook request appId is wrong data type', async () => {
|
||||
const httpsRequest = require('../lib/Adapters/Auth/httpsRequest');
|
||||
spyOn(httpsRequest, 'get').and.callFake(() => {
|
||||
return Promise.resolve({ id: 'a' });
|
||||
});
|
||||
const options = {
|
||||
facebook: {
|
||||
appIds: 'abcd',
|
||||
appSecret: 'secret_sauce',
|
||||
},
|
||||
};
|
||||
const authData = {
|
||||
access_token: 'badtoken',
|
||||
};
|
||||
const { adapter, appIds, providerOptions } = authenticationLoader.loadAuthAdapter(
|
||||
'facebook',
|
||||
options
|
||||
);
|
||||
await expectAsync(adapter.validateAppId(appIds, authData, providerOptions)).toBeRejectedWith(
|
||||
new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'appIds must be an array.')
|
||||
);
|
||||
});
|
||||
|
||||
it('should handle Facebook appSecret for validating appIds', async () => {
|
||||
const httpsRequest = require('../lib/Adapters/Auth/httpsRequest');
|
||||
spyOn(httpsRequest, 'get').and.callFake(() => {
|
||||
@@ -1652,7 +1629,7 @@ describe('apple signin auth adapter', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('(using client id as string) should throw error with with invalid jwt issuer', async () => {
|
||||
it('(using client id as string) should throw error with with invalid jwt issuer with token', async () => {
|
||||
const fakeClaim = {
|
||||
iss: 'https://not.apple.com',
|
||||
sub: 'the_user_id',
|
||||
@@ -2208,7 +2185,7 @@ describe('facebook limited auth adapter', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('(using client id as string) should throw error with with invalid jwt issuer', async () => {
|
||||
it('(using client id as string) with token', async () => {
|
||||
const fakeClaim = {
|
||||
iss: 'https://not.facebook.com',
|
||||
sub: 'the_user_id',
|
||||
|
||||
@@ -369,16 +369,6 @@ describe('Auth Adapter features', () => {
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should throw if no triggers found', async () => {
|
||||
await reconfigureServer({ auth: { wrongAdapter } });
|
||||
const user = new Parse.User();
|
||||
await expectAsync(
|
||||
user.save({ authData: { wrongAdapter: { id: 'wrongAdapter' } } })
|
||||
).toBeRejectedWithError(
|
||||
'Adapter is not configured. Implement either validateAuthData or all of the following: validateSetUp, validateLogin and validateUpdate'
|
||||
);
|
||||
});
|
||||
|
||||
it('should throw if policy does not match one of default/solo/additional', async () => {
|
||||
const adapterWithBadPolicy = {
|
||||
validateAppId: () => Promise.resolve(),
|
||||
|
||||
@@ -194,27 +194,6 @@ describe('cloud validator', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('set params on cloud functions', done => {
|
||||
Parse.Cloud.define(
|
||||
'hello',
|
||||
() => {
|
||||
return 'Hello world!';
|
||||
},
|
||||
{
|
||||
fields: ['a'],
|
||||
}
|
||||
);
|
||||
Parse.Cloud.run('hello', {})
|
||||
.then(() => {
|
||||
fail('function should have failed.');
|
||||
})
|
||||
.catch(error => {
|
||||
expect(error.code).toEqual(Parse.Error.VALIDATION_ERROR);
|
||||
expect(error.message).toEqual('Validation failed. Please specify data for a.');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('allow params on cloud functions', done => {
|
||||
Parse.Cloud.define(
|
||||
'hello',
|
||||
@@ -1629,7 +1608,7 @@ describe('cloud validator', () => {
|
||||
}
|
||||
});
|
||||
|
||||
it('Logs on invalid config', () => {
|
||||
it('Logs on multiple invalid configs', () => {
|
||||
const fields = [
|
||||
{
|
||||
field: 'otherKey',
|
||||
|
||||
@@ -49,6 +49,7 @@ describe('Cloud Code', () => {
|
||||
});
|
||||
|
||||
it('cloud code must be valid type', async () => {
|
||||
spyOn(console, 'error').and.callFake(() => {});
|
||||
await expectAsync(reconfigureServer({ cloud: true })).toBeRejectedWith(
|
||||
"argument 'cloud' must either be a string or a function"
|
||||
);
|
||||
|
||||
@@ -789,59 +789,11 @@ describe('Parse.File testing', () => {
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
Range: 'bytes=abc-efs',
|
||||
},
|
||||
}).catch(e => e);
|
||||
expect(file.headers['content-range']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('supports bytes range if start and end undefined', async () => {
|
||||
const headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
};
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1//files/file.txt ',
|
||||
body: repeat('argle bargle', 100),
|
||||
});
|
||||
const b = response.data;
|
||||
const file = await request({
|
||||
url: b.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
},
|
||||
}).catch(e => e);
|
||||
expect(file.headers['content-range']).toBeUndefined();
|
||||
});
|
||||
|
||||
it('supports bytes range if end is greater than size', async () => {
|
||||
const headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
'X-Parse-REST-API-Key': 'rest',
|
||||
};
|
||||
const response = await request({
|
||||
method: 'POST',
|
||||
headers: headers,
|
||||
url: 'http://localhost:8378/1//files/file.txt ',
|
||||
body: repeat('argle bargle', 100),
|
||||
});
|
||||
const b = response.data;
|
||||
const file = await request({
|
||||
url: b.url,
|
||||
headers: {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
'X-Parse-Application-Id': 'test',
|
||||
Range: 'bytes=0-2000',
|
||||
},
|
||||
}).catch(e => e);
|
||||
expect(file.headers['content-range']).toBe('bytes 0-1212/1212');
|
||||
});
|
||||
|
||||
it('supports bytes range if end is greater than size', async () => {
|
||||
const headers = {
|
||||
'Content-Type': 'application/octet-stream',
|
||||
|
||||
@@ -382,7 +382,6 @@ describe('ParseLiveQuery', function () {
|
||||
await obj2.save();
|
||||
obj2.set('foo', 'bart');
|
||||
await obj2.save();
|
||||
await sleep(2000);
|
||||
expect(createSpy).toHaveBeenCalledTimes(1);
|
||||
expect(updateSpy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -1633,35 +1633,6 @@ describe('ParseLiveQueryServer', function () {
|
||||
});
|
||||
});
|
||||
|
||||
it('matches CLP when find is restricted to userIds', done => {
|
||||
const parseLiveQueryServer = new ParseLiveQueryServer({});
|
||||
const acl = new Parse.ACL();
|
||||
acl.setReadAccess(testUserId, true);
|
||||
// Mock sessionTokenCache will return false when sessionToken is undefined
|
||||
const client = {
|
||||
sessionToken: 'sessionToken',
|
||||
getSubscriptionInfo: jasmine.createSpy('getSubscriptionInfo').and.returnValue({
|
||||
sessionToken: 'userId',
|
||||
}),
|
||||
};
|
||||
const requestId = 0;
|
||||
|
||||
parseLiveQueryServer
|
||||
._matchesCLP(
|
||||
{
|
||||
find: { userId: true },
|
||||
},
|
||||
{ className: 'Yolo' },
|
||||
client,
|
||||
requestId,
|
||||
'find'
|
||||
)
|
||||
.then(isMatched => {
|
||||
expect(isMatched).toBe(true);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('matches CLP when find is restricted to userIds', done => {
|
||||
const parseLiveQueryServer = new ParseLiveQueryServer({});
|
||||
const acl = new Parse.ACL();
|
||||
|
||||
@@ -362,7 +362,7 @@ describe_only_db('postgres')('PostgresStorageAdapter', () => {
|
||||
await dropTable(client, tableName);
|
||||
});
|
||||
|
||||
it('should use index for caseInsensitive query', async () => {
|
||||
it('should use index for caseInsensitive query with user', async () => {
|
||||
await adapter.deleteAllClasses();
|
||||
const config = Config.get('test');
|
||||
config.schemaCache.clear();
|
||||
|
||||
@@ -120,7 +120,7 @@ describe('PushWorker', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('transforms body appropriately', () => {
|
||||
it('transforms body appropriately with title locale', () => {
|
||||
const cleanBody = PushUtils.transformPushBodyForLocale(
|
||||
{
|
||||
data: {
|
||||
|
||||
@@ -286,6 +286,10 @@ afterEach(function (done) {
|
||||
.then(afterLogOut);
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
global.displaySlowTests();
|
||||
});
|
||||
|
||||
const TestObject = Parse.Object.extend({
|
||||
className: 'TestObject',
|
||||
});
|
||||
|
||||
@@ -1,15 +1,45 @@
|
||||
// Sets a global variable to the current test spec
|
||||
// ex: global.currentSpec.description
|
||||
|
||||
const { performance } = require('perf_hooks');
|
||||
global.currentSpec = null;
|
||||
|
||||
const timerMap = {};
|
||||
const duplicates = [];
|
||||
/** The minimum execution time in seconds for a test to be considered slow. */
|
||||
const slowTestLimit = 2;
|
||||
|
||||
class CurrentSpecReporter {
|
||||
specStarted(spec) {
|
||||
if (timerMap[spec.fullName]) {
|
||||
console.log('Duplicate spec: ' + spec.fullName);
|
||||
duplicates.push(spec.fullName);
|
||||
}
|
||||
timerMap[spec.fullName] = performance.now();
|
||||
global.currentSpec = spec;
|
||||
}
|
||||
specDone() {
|
||||
specDone(result) {
|
||||
if (result.status === 'excluded') {
|
||||
delete timerMap[result.fullName];
|
||||
return;
|
||||
}
|
||||
timerMap[result.fullName] = (performance.now() - timerMap[result.fullName]) / 1000;
|
||||
global.currentSpec = null;
|
||||
}
|
||||
}
|
||||
global.displaySlowTests = function() {
|
||||
const times = Object.values(timerMap).sort((a,b) => b - a);
|
||||
if (times.length > 0) {
|
||||
console.log(`Slow tests with execution time >=${slowTestLimit}s:`);
|
||||
}
|
||||
times.forEach((time) => {
|
||||
if (time >= slowTestLimit) {
|
||||
console.warn(`${time.toFixed(1)}s:`, Object.keys(timerMap).find(key => timerMap[key] === time));
|
||||
}
|
||||
});
|
||||
console.log('\n');
|
||||
duplicates.forEach((spec) => {
|
||||
console.warn('Duplicate spec: ' + spec);
|
||||
});
|
||||
};
|
||||
|
||||
module.exports = CurrentSpecReporter;
|
||||
|
||||
Reference in New Issue
Block a user