Merge branch 'master' into feat/db-adapters
This commit is contained in:
@@ -52,6 +52,88 @@ export default buildConfigWithDefaults({
|
||||
defaultValue: namedSaveToJWTValue,
|
||||
saveToJWT: saveToJWTKey,
|
||||
},
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'liftedSaveToJWT',
|
||||
type: 'text',
|
||||
saveToJWT: 'x-lifted-from-group',
|
||||
defaultValue: 'lifted from group',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'groupSaveToJWT',
|
||||
type: 'group',
|
||||
saveToJWT: 'x-group',
|
||||
fields: [
|
||||
{
|
||||
name: 'saveToJWTString',
|
||||
type: 'text',
|
||||
saveToJWT: 'x-test',
|
||||
defaultValue: 'nested property',
|
||||
},
|
||||
{
|
||||
name: 'saveToJWTFalse',
|
||||
type: 'text',
|
||||
saveToJWT: false,
|
||||
defaultValue: 'nested property',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
name: 'saveToJWTTab',
|
||||
saveToJWT: true,
|
||||
fields: [
|
||||
{
|
||||
name: 'test',
|
||||
type: 'text',
|
||||
saveToJWT: 'x-field',
|
||||
defaultValue: 'yes',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'tabSaveToJWTString',
|
||||
saveToJWT: 'tab-test',
|
||||
fields: [
|
||||
{
|
||||
name: 'includedByDefault',
|
||||
type: 'text',
|
||||
defaultValue: 'yes',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: 'No Name',
|
||||
fields: [
|
||||
{
|
||||
name: 'tabLiftedSaveToJWT',
|
||||
type: 'text',
|
||||
saveToJWT: true,
|
||||
defaultValue: 'lifted from unnamed tab',
|
||||
},
|
||||
{
|
||||
name: 'unnamedTabSaveToJWTString',
|
||||
type: 'text',
|
||||
saveToJWT: 'x-tab-field',
|
||||
defaultValue: 'text',
|
||||
},
|
||||
{
|
||||
name: 'unnamedTabSaveToJWTFalse',
|
||||
type: 'text',
|
||||
saveToJWT: false,
|
||||
defaultValue: 'false',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: 'custom',
|
||||
label: 'Custom',
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
import mongoose from 'mongoose';
|
||||
import jwtDecode from 'jwt-decode';
|
||||
import { GraphQLClient } from 'graphql-request';
|
||||
import payload from '../../src';
|
||||
import { initPayloadTest } from '../helpers/configHelpers';
|
||||
import { namedSaveToJWTValue, saveToJWTKey, slug } from './config';
|
||||
import { devUser } from '../credentials';
|
||||
import type { User } from '../../src/auth';
|
||||
import configPromise from '../collections-graphql/config';
|
||||
|
||||
require('isomorphic-fetch');
|
||||
|
||||
let apiUrl;
|
||||
let client: GraphQLClient;
|
||||
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
@@ -20,6 +23,9 @@ describe('Auth', () => {
|
||||
beforeAll(async () => {
|
||||
const { serverURL } = await initPayloadTest({ __dirname, init: { local: false } });
|
||||
apiUrl = `${serverURL}/api`;
|
||||
const config = await configPromise;
|
||||
const url = `${serverURL}${config.routes.api}${config.routes.graphQL}`;
|
||||
client = new GraphQLClient(url);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@@ -28,7 +34,50 @@ describe('Auth', () => {
|
||||
}
|
||||
});
|
||||
|
||||
describe('admin user', () => {
|
||||
describe('GraphQL - admin user', () => {
|
||||
let token;
|
||||
let user;
|
||||
beforeAll(async () => {
|
||||
// language=graphQL
|
||||
const query = `mutation {
|
||||
loginUser(email: "${devUser.email}", password: "${devUser.password}") {
|
||||
token
|
||||
user {
|
||||
id
|
||||
email
|
||||
}
|
||||
}
|
||||
}`;
|
||||
const response = await client.request(query);
|
||||
user = response.loginUser.user;
|
||||
token = response.loginUser.token;
|
||||
});
|
||||
|
||||
it('should login', async () => {
|
||||
expect(user.id).toBeDefined();
|
||||
expect(user.email).toEqual(devUser.email);
|
||||
expect(token).toBeDefined();
|
||||
});
|
||||
|
||||
it('should have fields saved to JWT', async () => {
|
||||
const decoded = jwtDecode<User>(token);
|
||||
const {
|
||||
email: jwtEmail,
|
||||
collection,
|
||||
roles,
|
||||
iat,
|
||||
exp,
|
||||
} = decoded;
|
||||
|
||||
expect(jwtEmail).toBeDefined();
|
||||
expect(collection).toEqual('users');
|
||||
expect(Array.isArray(roles)).toBeTruthy();
|
||||
expect(iat).toBeDefined();
|
||||
expect(exp).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('REST - admin user', () => {
|
||||
beforeAll(async () => {
|
||||
await fetch(`${apiUrl}/${slug}/first-register`, {
|
||||
body: JSON.stringify({
|
||||
@@ -103,20 +152,39 @@ describe('Auth', () => {
|
||||
});
|
||||
|
||||
it('should have fields saved to JWT', async () => {
|
||||
const decoded = jwtDecode<User>(token);
|
||||
const {
|
||||
email: jwtEmail,
|
||||
collection,
|
||||
roles,
|
||||
[saveToJWTKey]: customJWTPropertyKey,
|
||||
'x-lifted-from-group': liftedFromGroup,
|
||||
'x-tab-field': unnamedTabSaveToJWTString,
|
||||
tabLiftedSaveToJWT,
|
||||
unnamedTabSaveToJWTFalse,
|
||||
iat,
|
||||
exp,
|
||||
} = jwtDecode<User>(token);
|
||||
} = decoded;
|
||||
|
||||
const group = decoded['x-group'] as Record<string, unknown>;
|
||||
const tab = decoded.saveToJWTTab as Record<string, unknown>;
|
||||
const tabString = decoded['tab-test'] as Record<string, unknown>;
|
||||
|
||||
expect(jwtEmail).toBeDefined();
|
||||
expect(collection).toEqual('users');
|
||||
expect(collection).toEqual('users');
|
||||
expect(Array.isArray(roles)).toBeTruthy();
|
||||
// 'x-custom-jwt-property-name': 'namedSaveToJWT value'
|
||||
expect(customJWTPropertyKey).toEqual(namedSaveToJWTValue);
|
||||
expect(group).toBeDefined();
|
||||
expect(group['x-test']).toEqual('nested property');
|
||||
expect(group.saveToJWTFalse).toBeUndefined();
|
||||
expect(liftedFromGroup).toEqual('lifted from group');
|
||||
expect(tabLiftedSaveToJWT).toEqual('lifted from unnamed tab');
|
||||
expect(tab['x-field']).toEqual('yes');
|
||||
expect(tabString.includedByDefault).toEqual('yes');
|
||||
expect(unnamedTabSaveToJWTString).toEqual('text');
|
||||
expect(unnamedTabSaveToJWTFalse).toBeUndefined();
|
||||
expect(iat).toBeDefined();
|
||||
expect(exp).toBeDefined();
|
||||
});
|
||||
|
||||
@@ -203,6 +203,42 @@ const BlockFields: CollectionConfig = {
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'blocks',
|
||||
name: 'blocksWithSimilarConfigs',
|
||||
blocks: [{
|
||||
slug: 'block-1',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'block-2',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title2',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
|
||||
@@ -368,6 +368,29 @@ describe('fields', () => {
|
||||
await expect(firstRow).toBeVisible();
|
||||
await expect(firstRow.locator('.blocks-field__block-pill-text')).toContainText('Text en');
|
||||
});
|
||||
|
||||
test('should add different blocks with similar field configs', async () => {
|
||||
await page.goto(url.create);
|
||||
|
||||
async function addBlock(name: 'Block 1' | 'Block 2') {
|
||||
await page.locator('#field-blocksWithSimilarConfigs').getByRole('button', { name: 'Add Blocks With Similar Config' }).click();
|
||||
await page.getByRole('button', { name }).click();
|
||||
}
|
||||
|
||||
await addBlock('Block 1');
|
||||
|
||||
await page.locator('#blocksWithSimilarConfigs-row-0').getByRole('button', { name: 'Add Item' }).click();
|
||||
await page.locator('input[name="blocksWithSimilarConfigs.0.items.0.title"]').fill('items>0>title');
|
||||
|
||||
expect(await page.locator('input[name="blocksWithSimilarConfigs.0.items.0.title"]').inputValue()).toEqual('items>0>title');
|
||||
|
||||
await addBlock('Block 2');
|
||||
|
||||
await page.locator('#blocksWithSimilarConfigs-row-1').getByRole('button', { name: 'Add Item' }).click();
|
||||
await page.locator('input[name="blocksWithSimilarConfigs.1.items.0.title2"]').fill('items>1>title');
|
||||
|
||||
expect(await page.locator('input[name="blocksWithSimilarConfigs.1.items.0.title2"]').inputValue()).toEqual('items>1>title');
|
||||
});
|
||||
});
|
||||
|
||||
describe('array', () => {
|
||||
|
||||
@@ -85,6 +85,89 @@ export default buildConfigWithDefaults({
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
{
|
||||
type: 'tabs',
|
||||
label: 'Tabs',
|
||||
tabs: [{
|
||||
label: 'Tab 1',
|
||||
name: 'tab1',
|
||||
fields: [
|
||||
{
|
||||
type: 'blocks',
|
||||
name: 'layout',
|
||||
blocks: [{
|
||||
slug: 'block-1',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'block-2',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title2',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
{
|
||||
type: 'blocks',
|
||||
name: 'blocksWithSimilarConfigs',
|
||||
blocks: [{
|
||||
slug: 'block-1',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
slug: 'block-2',
|
||||
fields: [
|
||||
{
|
||||
type: 'array',
|
||||
name: 'items',
|
||||
fields: [
|
||||
{
|
||||
type: 'text',
|
||||
name: 'title2',
|
||||
required: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
}],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user