Feat: nested collections (#3716)

This commit is contained in:
Erez Rokah
2020-06-18 10:11:37 +03:00
committed by GitHub
parent b4c47caf59
commit af7bbbd9a9
89 changed files with 8269 additions and 5619 deletions

View File

@ -1597,7 +1597,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"e774625f38ae12e6bdc27574f3238a20bf71b6ca\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"e774625f38ae12e6bdc27574f3238a20bf71b6ca\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/.netlify/git/github/git/trees",
"headers": {

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1284,7 +1284,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"d8e02516ac6e201f752b6c1916a2a850fa0ae2eb\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"d8e02516ac6e201f752b6c1916a2a850fa0ae2eb\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/forkOwner/repo/git/trees",
"headers": {

View File

@ -1235,7 +1235,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"8ac793644b57607b35a15858b44ed7d90b794e73\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"8ac793644b57607b35a15858b44ed7d90b794e73\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/owner/repo/git/trees",
"headers": {

View File

@ -1183,7 +1183,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"c502fbb54c429d6b7fc056e86ad5739bb96283a0\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"c502fbb54c429d6b7fc056e86ad5739bb96283a0\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/owner/repo/git/trees",
"headers": {

View File

@ -1462,7 +1462,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"a9e732737e1a806d311ba91ff6c42de528a69b5d\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"a9e732737e1a806d311ba91ff6c42de528a69b5d\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/forkOwner/repo/git/trees",
"headers": {

View File

@ -1286,7 +1286,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"49f07bd3fa298db5d2f430a5b04bbfa60978eed8\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"49f07bd3fa298db5d2f430a5b04bbfa60978eed8\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/owner/repo/git/trees",
"headers": {

View File

@ -1234,7 +1234,7 @@
"status": 200
},
{
"body": "{\"base_tree\":\"1c11a4511b2208a3a3d159035962f5ac267df45c\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":null},{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"body": "{\"base_tree\":\"1c11a4511b2208a3a3d159035962f5ac267df45c\",\"tree\":[{\"path\":\"content/posts/1970-01-01-first-title.md\",\"mode\":\"100644\",\"type\":\"blob\",\"sha\":\"5ed1cbc40b517ab0b1dba1f9486d6c2723e7020e\"}]}",
"method": "POST",
"url": "/repos/owner/repo/git/trees",
"headers": {

View File

@ -22,8 +22,10 @@ import {
populateEntry,
publishAndCreateNewEntryInEditor,
publishAndDuplicateEntryInEditor,
assertNotification,
assertFieldValidationError,
} from '../utils/steps';
import { workflowStatus, editorStatus, publishTypes } from '../utils/constants';
import { workflowStatus, editorStatus, publishTypes, notifications } from '../utils/constants';
const entry1 = {
title: 'first title',
@ -192,4 +194,123 @@ describe('Test Backend Editorial Workflow', () => {
updateWorkflowStatusInEditor(editorStatus.ready);
publishAndDuplicateEntryInEditor(entry1);
});
const inSidebar = func => {
cy.get('[class*=SidebarNavList]').within(func);
};
const inGrid = func => {
cy.get('[class*=CardsGrid]').within(func);
};
it('can access nested collection items', () => {
login();
inSidebar(() => cy.contains('a', 'Pages').click());
inSidebar(() => cy.contains('a', 'Directory'));
inGrid(() => cy.contains('a', 'Root Page'));
inGrid(() => cy.contains('a', 'Directory'));
inSidebar(() => cy.contains('a', 'Directory').click());
inGrid(() => cy.contains('a', 'Sub Directory'));
inGrid(() => cy.contains('a', 'Another Sub Directory'));
inSidebar(() => cy.contains('a', 'Sub Directory').click());
inGrid(() => cy.contains('a', 'Nested Directory'));
cy.url().should(
'eq',
'http://localhost:8080/#/collections/pages/filter/directory/sub-directory',
);
inSidebar(() => cy.contains('a', 'Pages').click());
inSidebar(() => cy.contains('a', 'Pages').click());
inGrid(() => cy.contains('a', 'Another Sub Directory').should('not.exist'));
});
it('can navigate to nested entry', () => {
login();
inSidebar(() => cy.contains('a', 'Pages').click());
inSidebar(() => cy.contains('a', 'Directory').click());
inGrid(() => cy.contains('a', 'Another Sub Directory').click());
cy.url().should(
'eq',
'http://localhost:8080/#/collections/pages/entries/directory/another-sub-directory/index',
);
});
it(`can create a new entry with custom path`, () => {
login();
inSidebar(() => cy.contains('a', 'Pages').click());
inSidebar(() => cy.contains('a', 'Directory').click());
inSidebar(() => cy.contains('a', 'Sub Directory').click());
cy.contains('a', 'New Page').click();
cy.get('[id^="path-field"]').should('have.value', 'directory/sub-directory');
cy.get('[id^="path-field"]').type('/new-path');
cy.get('[id^="title-field"]').type('New Path Title');
cy.clock().then(clock => {
clock.tick(150);
});
cy.contains('button', 'Save').click();
assertNotification(notifications.saved);
updateWorkflowStatusInEditor(editorStatus.ready);
publishEntryInEditor(publishTypes.publishNow);
exitEditor();
inGrid(() => cy.contains('a', 'New Path Title'));
inSidebar(() => cy.contains('a', 'Directory').click());
inSidebar(() => cy.contains('a', 'Directory').click());
inGrid(() => cy.contains('a', 'New Path Title').should('not.exist'));
});
it(`can't create an entry with an existing path`, () => {
login();
inSidebar(() => cy.contains('a', 'Pages').click());
inSidebar(() => cy.contains('a', 'Directory').click());
inSidebar(() => cy.contains('a', 'Sub Directory').click());
cy.contains('a', 'New Page').click();
cy.get('[id^="title-field"]').type('New Path Title');
cy.clock().then(clock => {
clock.tick(150);
});
cy.contains('button', 'Save').click();
assertFieldValidationError({
message: `Path 'directory/sub-directory' already exists`,
fieldLabel: 'Path',
});
});
it('can move an existing entry to a new path', () => {
login();
inSidebar(() => cy.contains('a', 'Pages').click());
inGrid(() => cy.contains('a', 'Directory').click());
cy.get('[id^="path-field"]').should('have.value', 'directory');
cy.get('[id^="path-field"]').clear();
cy.get('[id^="path-field"]').type('new-directory');
cy.get('[id^="title-field"]').clear();
cy.get('[id^="title-field"]').type('New Directory');
cy.clock().then(clock => {
clock.tick(150);
});
cy.contains('button', 'Save').click();
assertNotification(notifications.saved);
updateWorkflowStatusInEditor(editorStatus.ready);
publishEntryInEditor(publishTypes.publishNow);
exitEditor();
inSidebar(() => cy.contains('a', 'New Directory').click());
inGrid(() => cy.contains('a', 'Sub Directory'));
inGrid(() => cy.contains('a', 'Another Sub Directory'));
});
});

View File

@ -1,3 +1,4 @@
import '../utils/dismiss-local-backup';
import {
login,
newPost,

View File

@ -107,7 +107,7 @@ async function deleteRepositories({ owner, repo, tempDir }) {
console.log('Deleting repository', `${owner}/${repo}`);
await fs.remove(tempDir);
let client = getGitLabClient(token);
const client = getGitLabClient(token);
await client.Projects.remove(`${owner}/${repo}`).catch(errorHandler);
}

View File

@ -34,8 +34,8 @@ const matchRoute = (route, fetchArgs) => {
const options = fetchArgs[1];
const method = options && options.method ? options.method : 'GET';
let body = options && options.body;
let routeBody = route.body;
const body = options && options.body;
const routeBody = route.body;
let bodyMatch = false;
if (routeBody?.encoding === 'base64' && ['File', 'Blob'].includes(body?.constructor.name)) {

View File

@ -43,6 +43,7 @@ const retrieveRecordedExpectations = async () => {
(Host.includes('bitbucket.org') && httpRequest.path.includes('info/lfs')) ||
Host.includes('api.media.atlassian.com') ||
Host.some(host => host.includes('netlify.com')) ||
Host.some(host => host.includes('netlify.app')) ||
Host.some(host => host.includes('s3.amazonaws.com'))
);
});

View File

@ -76,7 +76,7 @@ function assertColorOn(cssProperty, color, opts) {
}
function exitEditor() {
cy.contains('a[href^="#/collections/"]', 'Writing in').click();
cy.contains('a', 'Writing in').click();
}
function goToWorkflow() {
@ -684,4 +684,6 @@ module.exports = {
duplicatePostAndPublish,
publishAndCreateNewEntryInEditor,
publishAndDuplicateEntryInEditor,
assertNotification,
assertFieldValidationError,
};