chore: passing tests

This commit is contained in:
James
2023-07-31 18:12:09 -04:00
parent af302e19ee
commit 3a5851d28a
21 changed files with 246 additions and 89 deletions

View File

@@ -18,7 +18,7 @@
"dependencies": {
"bson-objectid": "^2.0.4",
"deepmerge": "^4.3.1",
"get-port": "^7.0.0",
"get-port": "5.1.1",
"mongoose": "6.11.4",
"mongoose-aggregate-paginate-v2": "^1.0.6",
"mongoose-paginate-v2": "1.7.22",

View File

@@ -3318,16 +3318,11 @@ get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@
has-proto "^1.0.1"
has-symbols "^1.0.3"
get-port@^5.1.1:
get-port@5.1.1, get-port@^5.1.1:
version "5.1.1"
resolved "https://registry.npmjs.org/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193"
integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==
get-port@^7.0.0:
version "7.0.0"
resolved "https://registry.npmjs.org/get-port/-/get-port-7.0.0.tgz#ffcd83da826146529e307a341d7801cae351daff"
integrity sha512-mDHFgApoQd+azgMdwylJrv2DX47ywGq1i5VFJE7fZ0dttNq3iQMfsU4IvEgBHojA3KqEudyu7Vq+oN8kNaNkWw==
get-stdin@^8.0.0:
version "8.0.0"
resolved "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53"

View File

@@ -34,7 +34,7 @@ async function verifyEmail(args: Args): Promise<boolean> {
where: { id: { equals: user.id } },
data: {
_verified: true,
_verificationToken: undefined,
_verificationToken: null,
},
req,
});

View File

@@ -13,7 +13,6 @@ export async function generateGraphQLSchema(): Promise<void> {
await payload.init({
secret: '--unused--',
mongoURL: false,
local: true,
});

View File

@@ -401,14 +401,10 @@ type IndexOptions = {
unique?: boolean;
/** Override the autogenerated index name (useful if the resulting name is larger than 128 bytes) */
name?: string;
/** Creates a partial index based on the given filter object (MongoDB 3.2 or higher) */
partialFilterExpression?: Document;
/** Creates a sparse index. */
sparse?: boolean;
/** Allows you to expire data on indexes applied to a data (MongoDB 2.2 or higher) */
expireAfterSeconds?: number;
/** Allows users to configure the storage engine on a per-index basis when creating an index. (MongoDB 3.0 or higher) */
storageEngine?: Document;
/** (MongoDB 4.4. or higher) Specifies how many data-bearing members of a replica set, including the primary, must complete the index builds successfully before the primary marks the indexes as ready. This option accepts the same values for the "w" field in a write concern plus "votingMembers", which indicates all voting data-bearing nodes. */
commitQuorum?: number | string;
/** Specifies the index version number, either 0 or 1. */
@@ -423,7 +419,6 @@ type IndexOptions = {
/** For geospatial indexes set the high bound for the co-ordinates. */
max?: number;
bucketSize?: number;
wildcardProjection?: Document;
/** Specifies that the index should exist on the target collection but should not be used by the query planner when executing operations. (MongoDB 4.4 or higher) */
hidden?: boolean;
}

View File

@@ -5,7 +5,6 @@ import { Options as ExpressFileUploadOptions } from 'express-fileupload';
import type { Configuration } from 'webpack';
import SMTPConnection from 'nodemailer/lib/smtp-connection';
import GraphQL from 'graphql';
import { ConnectOptions } from 'mongoose';
import React from 'react';
import { DestinationStream, LoggerOptions } from 'pino';
import type { InitOptions as i18nInitOptions } from 'i18next';
@@ -81,13 +80,6 @@ export type GraphQLExtension = (
export type InitOptions = {
/** Express app for Payload to use */
express?: Express;
/** MongoDB connection URL, starts with `mongo` */
mongoURL?: string | false;
/** Extra configuration options that will be passed to MongoDB */
mongoOptions?: ConnectOptions & {
/** Set false to disable $facet aggregation in non-supporting databases, Defaults to true */
useFacet?: boolean
};
/** Secure string that Payload will use for any encryption workflows */
secret: string;

View File

@@ -88,18 +88,6 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
secret: string;
mongoURL: string | false;
mongoOptions: InitOptions['mongoOptions'];
/**
* @deprecated
*
* This will be removed in 2.0.0 and will become the responsibility
* of the database adapter itself
*/
mongoMemoryServer: any;
local: boolean;
encrypt = encrypt;
@@ -148,8 +136,6 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
*/
async init(options: InitOptions): Promise<Payload> {
this.logger = Logger('payload', options.loggerOptions, options.loggerDestination);
this.mongoURL = options.mongoURL;
this.mongoOptions = options.mongoOptions;
this.logger.info('Starting Payload...');
if (!options.secret) {
@@ -222,7 +208,7 @@ export class BasePayload<TGeneratedTypes extends GeneratedTypes> {
serverInitTelemetry(this);
if (options.local !== false && this.mongoURL) {
if (options.local !== false) {
if (typeof options.onInit === 'function') await options.onInit(this);
if (typeof this.config.onInit === 'function') await this.config.onInit(this);
}

View File

@@ -34,7 +34,9 @@ describe('_Community Tests', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
// --__--__--__--__--__--__--__--__--__

View File

@@ -36,7 +36,9 @@ describe('Access Control', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
it('should not affect hidden fields when patching data', async () => {

View File

@@ -1,4 +1,5 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
@@ -14,6 +15,8 @@ export interface Config {
'group-one-collection-twos': GroupOneCollectionTwo;
'group-two-collection-ones': GroupTwoCollectionOne;
'group-two-collection-twos': GroupTwoCollectionTwo;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
};
globals: {
'hidden-global': HiddenGlobal;
@@ -24,11 +27,13 @@ export interface Config {
}
export interface User {
id: string;
createdAt: string;
updatedAt: string;
email?: string;
createdAt: string;
email: string;
resetPasswordToken?: string;
resetPasswordExpiration?: string;
salt?: string;
hash?: string;
loginAttempts?: number;
lockUntil?: string;
password?: string;
@@ -36,8 +41,8 @@ export interface User {
export interface HiddenCollection {
id: string;
title?: string;
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface Post {
id: string;
@@ -47,46 +52,89 @@ export interface Post {
richText?: {
[k: string]: unknown;
}[];
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface GroupOneCollectionOne {
id: string;
title?: string;
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface GroupOneCollectionTwo {
id: string;
title?: string;
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface GroupTwoCollectionOne {
id: string;
title?: string;
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface GroupTwoCollectionTwo {
id: string;
title?: string;
createdAt: string;
updatedAt: string;
createdAt: string;
}
export interface PayloadPreference {
id: string;
user: {
value: string | User;
relationTo: 'users';
};
key?: string;
value?:
| {
[k: string]: unknown;
}
| unknown[]
| string
| number
| boolean
| null;
updatedAt: string;
createdAt: string;
}
export interface PayloadMigration {
id: string;
name?: string;
batch?: number;
schema?:
| {
[k: string]: unknown;
}
| unknown[]
| string
| number
| boolean
| null;
updatedAt: string;
createdAt: string;
}
export interface HiddenGlobal {
id: string;
title?: string;
updatedAt?: string;
createdAt?: string;
}
export interface Global {
id: string;
title?: string;
updatedAt?: string;
createdAt?: string;
}
export interface GroupGlobalsOne {
id: string;
title?: string;
updatedAt?: string;
createdAt?: string;
}
export interface GroupGlobalsTwo {
id: string;
title?: string;
updatedAt?: string;
createdAt?: string;
}

View File

@@ -12,7 +12,9 @@ describe('array-update', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
it('should persist existing array-based data while updating and passing row ID', async () => {

View File

@@ -75,6 +75,13 @@ export default buildConfigWithDefaults({
},
fields: [],
},
{
slug: 'public-users',
auth: {
verify: true,
},
fields: [],
},
],
onInit: async (payload) => {
await payload.create({

View File

@@ -19,7 +19,9 @@ describe('AuthStrategies', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
describe('create user', () => {

View File

@@ -1,4 +1,3 @@
import mongoose from 'mongoose';
import payload from '../../src';
import { initPayloadTest } from '../helpers/configHelpers';
import { slug } from './config';
@@ -22,7 +21,9 @@ describe('Auth', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
describe('admin user', () => {
@@ -191,7 +192,7 @@ describe('Auth', () => {
expect(doc).toHaveProperty('roles');
});
it.skip('should allow verification of a user', async () => {
it('should allow verification of a user', async () => {
const emailToVerify = 'verify@me.com';
const response = await fetch(`${apiUrl}/public-users`, {
body: JSON.stringify({
@@ -207,14 +208,19 @@ describe('Auth', () => {
});
expect(response.status).toBe(201);
// const client = await MongoClient.connect(`${mongoURL}:${mongoPort}`, {
// useUnifiedTopology: true,
// });
// const db = client.db(mongoDBName);
const { db } = mongoose.connection;
const userResult = await db.collection('public-users').findOne({ email: emailToVerify });
const { _verified, _verificationToken } = userResult;
const userResult = await payload.find({
collection: 'public-users',
limit: 1,
showHiddenFields: true,
where: {
email: {
equals: emailToVerify,
},
},
});
const { _verified, _verificationToken } = userResult.docs[0];
expect(_verified).toBe(false);
expect(_verificationToken).toBeDefined();
@@ -228,11 +234,20 @@ describe('Auth', () => {
expect(verificationResponse.status).toBe(200);
const afterVerifyResult = await db.collection('public-users').findOne({ email: emailToVerify });
// @ts-expect-error trust
const { _verified: afterVerified, _verificationToken: afterToken } = afterVerifyResult;
const afterVerifyResult = await payload.find({
collection: 'public-users',
limit: 1,
showHiddenFields: true,
where: {
email: {
equals: emailToVerify,
},
},
});
const { _verified: afterVerified, _verificationToken: afterToken } = afterVerifyResult.docs[0];
expect(afterVerified).toBe(true);
expect(afterToken).toBeUndefined();
expect(afterToken).toBeNull();
});
describe('Account Locking', () => {
@@ -283,8 +298,18 @@ describe('Auth', () => {
await tryLogin();
await tryLogin();
const userResult = await mongoose.connection.db.collection(slug).findOne<any>({ email: userEmail });
const { loginAttempts, lockUntil } = userResult;
const userResult = await payload.find({
collection: slug,
limit: 1,
showHiddenFields: true,
where: {
email: {
equals: userEmail,
},
},
});
const { loginAttempts, lockUntil } = userResult.docs[0];
expect(loginAttempts).toBe(2);
expect(lockUntil).toBeDefined();
@@ -295,10 +320,17 @@ describe('Auth', () => {
await tryLogin();
await tryLogin();
// set lockUntil
await mongoose.connection.db
.collection(slug)
.findOneAndUpdate({ email: userEmail }, { $set: { lockUntil: Date.now() - 605 * 1000 } });
await payload.update({
collection: slug,
where: {
email: {
equals: userEmail,
},
},
data: {
lockUntil: Date.now() - 605 * 1000,
},
});
// login
await fetch(`${apiUrl}/${slug}/login`, {
@@ -313,10 +345,18 @@ describe('Auth', () => {
method: 'post',
});
const userResult = await mongoose.connection.db
.collection(slug)
.findOne<any>({ email: userEmail });
const { loginAttempts, lockUntil } = userResult;
const userResult = await payload.find({
collection: slug,
limit: 1,
showHiddenFields: true,
where: {
email: {
equals: userEmail,
},
},
});
const { loginAttempts, lockUntil } = userResult.docs[0];
expect(loginAttempts).toBe(0);
expect(lockUntil).toBeNull();

View File

@@ -1,26 +1,103 @@
/* tslint:disable */
/* eslint-disable */
/**
* This file was automatically generated by Payload.
* DO NOT MODIFY IT BY HAND. Instead, modify your source Payload config,
* and re-run `payload generate:types` to regenerate this file.
*/
export interface Config {}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "users".
*/
export interface Config {
collections: {
users: User;
'api-keys': ApiKey;
'public-users': PublicUser;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
};
globals: {};
}
export interface User {
id: string;
roles: ('admin' | 'editor' | 'moderator' | 'user' | 'viewer')[];
custom?: string;
updatedAt: string;
createdAt: string;
enableAPIKey?: boolean;
apiKey?: string;
apiKeyIndex?: string;
email?: string;
email: string;
resetPasswordToken?: string;
resetPasswordExpiration?: string;
salt?: string;
hash?: string;
loginAttempts?: number;
lockUntil?: string;
createdAt: string;
updatedAt: string;
password?: string;
}
export interface ApiKey {
id: string;
updatedAt: string;
createdAt: string;
enableAPIKey?: boolean;
apiKey?: string;
apiKeyIndex?: string;
}
export interface PublicUser {
id: string;
updatedAt: string;
createdAt: string;
email: string;
resetPasswordToken?: string;
resetPasswordExpiration?: string;
salt?: string;
hash?: string;
_verified?: boolean;
_verificationToken?: string;
loginAttempts?: number;
lockUntil?: string;
password?: string;
}
export interface PayloadPreference {
id: string;
user:
| {
value: string | User;
relationTo: 'users';
}
| {
value: string | ApiKey;
relationTo: 'api-keys';
}
| {
value: string | PublicUser;
relationTo: 'public-users';
};
key?: string;
value?:
| {
[k: string]: unknown;
}
| unknown[]
| string
| number
| boolean
| null;
updatedAt: string;
createdAt: string;
}
export interface PayloadMigration {
id: string;
name?: string;
batch?: number;
schema?:
| {
[k: string]: unknown;
}
| unknown[]
| string
| number
| boolean
| null;
updatedAt: string;
createdAt: string;
}

View File

@@ -17,7 +17,9 @@ describe('collections-graphql', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
describe('CRUD', () => {

View File

@@ -16,7 +16,9 @@ describe('collections-rest', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
beforeEach(async () => {

View File

@@ -14,7 +14,7 @@ import { defaultNumber, numberDoc } from './collections/Number';
import { dateDoc } from './collections/Date';
import type { RichTextField } from './payload-types';
import type { PaginatedDocs } from '../../src/database/types';
import type { MongooseAdapter } from '../../src/database/adapters/mongoose';
import type { MongooseAdapter } from '../../packages/db-mongodb/src';
let client;
let graphQLClient: GraphQLClient;
@@ -319,7 +319,7 @@ describe('Fields', () => {
const options: Record<string, IndexOptions> = {};
beforeAll(() => {
indexes = payload.versions['indexed-fields'].schema.indexes() as [Record<string, IndexDirection>, IndexOptions];
indexes = (payload.db as MongooseAdapter).versions['indexed-fields'].schema.indexes() as [Record<string, IndexDirection>, IndexOptions];
indexes.forEach((index) => {
const field = Object.keys(index[0])[0];
definitions[field] = index[0][field];

View File

@@ -24,7 +24,9 @@ describe('Hooks', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
describe('transform actions', () => {

View File

@@ -60,7 +60,9 @@ describe('Localization', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
describe('localized text', () => {

View File

@@ -32,7 +32,9 @@ describe('Relationships', () => {
});
afterAll(async () => {
if (typeof payload.db.destroy === 'function') {
await payload.db.destroy(payload);
}
});
beforeEach(async () => {