Просмотр исходного кода

Merge branch 'imprv/refacter-recursively' into imprv/4685-4987-impl-test-for-renameDecendants-

itizawa 5 лет назад
Родитель
Сommit
ac054bdb48

+ 5 - 2
CHANGES.md

@@ -1,10 +1,13 @@
 # CHANGES
 
-
-## v.4.2.7
+## v4.2.8-RC
 
 * 
 
+## v4.2.7
+
+* Fix: Installer doesn't work on Chrome
+
 ## v4.2.6
 
 * Fix: Failed to save temporaryUrlCached with using gcs

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "growi",
-  "version": "4.2.7-RC",
+  "version": "4.2.8-RC",
   "description": "Team collaboration software using markdown",
   "tags": [
     "wiki",

+ 13 - 8
src/client/js/components/InstallerForm.jsx

@@ -13,12 +13,12 @@ class InstallerForm extends React.Component {
 
     this.state = {
       isValidUserName: true,
-      isSubmitButtonDisabled: false,
+      isSubmittingDisabled: false,
       selectedLang: {},
     };
     // this.checkUserName = this.checkUserName.bind(this);
 
-    this.clickHandler = this.clickHandler.bind(this);
+    this.submitHandler = this.submitHandler.bind(this);
   }
 
   componentWillMount() {
@@ -42,11 +42,17 @@ class InstallerForm extends React.Component {
     this.setState({ selectedLang: meta });
   }
 
-  clickHandler() {
-    this.setState({ isSubmitButtonDisabled: true });
+  submitHandler() {
+    if (this.state.isSubmittingDisabled) {
+      return;
+    }
+
+    this.setState({ isSubmittingDisabled: true });
     setTimeout(() => {
-      this.setState({ isSubmitButtonDisabled: false });
+      this.setState({ isSubmittingDisabled: false });
     }, 3000);
+
+    document['register-form'].submit();
   }
 
   render() {
@@ -66,7 +72,7 @@ class InstallerForm extends React.Component {
           </div>
         </div>
         <div className="row">
-          <form role="form" action="/installer" method="post" id="register-form" className="col-md-12">
+          <form role="form" action="/installer" method="post" id="register-form" className="col-md-12" onSubmit={this.submitHandler}>
             <div className="dropdown mb-3">
               <div className="d-flex dropdown-with-icon">
                 <i className="icon-bubbles border-0 rounded-0" />
@@ -163,8 +169,7 @@ class InstallerForm extends React.Component {
                 type="submit"
                 className="btn-fill btn btn-register"
                 id="register"
-                disabled={this.state.isSubmitButtonDisabled}
-                onClick={this.clickHandler}
+                disabled={this.state.isSubmittingDisabled}
               >
                 <div className="eff"></div>
                 <span className="btn-label"><i className="icon-user-follow" /></span>

+ 2 - 2
src/server/routes/hackmd.js

@@ -191,8 +191,8 @@ module.exports = function(crowi, app) {
 
     const { status, headers } = hackmdResponse;
 
-    // validate HackMD/CodiMD specific header
-    if (headers['codimd-version'] == null && headers['hackmd-version'] == null) {
+    // validate HackMD/CodiMD/HedgeDoc specific header
+    if (headers['codimd-version'] == null && headers['hackmd-version'] == null && headers['hedgedoc-version'] == null) {
       const message = 'Connecting to a non-HackMD server.';
       logger.error(message);
       return res.json(ApiResponse.error(message));

+ 2 - 0
src/server/service/page.js

@@ -232,6 +232,8 @@ class PageService {
     options.grantUserGroupId = page.grantedGroup;
     options.grantedUsers = page.grantedUsers;
 
+    newPagePath = this.crowi.xss.process(newPagePath); // eslint-disable-line no-param-reassign
+
     const createdPage = await Page.create(
       newPagePath, page.revision.body, user, options,
     );

+ 43 - 4
src/test/service/page.test.js

@@ -35,6 +35,7 @@ describe('PageService', () => {
   let User;
   let Tag;
   let PageTagRelation;
+  let xssSpy;
 
   beforeAll(async(done) => {
     crowi = await getInstance();
@@ -101,6 +102,7 @@ describe('PageService', () => {
         grant: Page.GRANT_PUBLIC,
         creator: testUser1,
         lastUpdateUser: testUser1,
+        revision: '600d395667536503354cbe91',
       },
       {
         path: '/parentForDuplicate/child',
@@ -179,11 +181,21 @@ describe('PageService', () => {
       { relatedPage: childForDuplicate, relatedTag: childTag },
     ]);
 
+    await Revision.insertMany([
+      {
+        _id: '600d395667536503354cbe91',
+        path: parentForDuplicate,
+        body: 'duplicateBody',
+      },
+    ]);
+
+    xssSpy = jest.spyOn(crowi.xss, 'process').mockImplementation(path => path);
+
+
     done();
   });
 
   describe('rename page', () => {
-    let xssSpy;
     let pageEventSpy;
     let renameDescendantsWithStreamSpy;
     const dateToUse = new Date('2000-01-01');
@@ -191,7 +203,6 @@ describe('PageService', () => {
 
     beforeEach(async(done) => {
       jest.spyOn(global.Date, 'now').mockImplementation(() => dateToUse);
-      xssSpy = jest.spyOn(crowi.xss, 'process').mockImplementation(path => path);
       pageEventSpy = jest.spyOn(crowi.pageService.pageEvent, 'emit').mockImplementation();
       renameDescendantsWithStreamSpy = jest.spyOn(crowi.pageService, 'renameDescendantsWithStream').mockImplementation();
       done();
@@ -350,8 +361,36 @@ describe('PageService', () => {
 
 
   describe('duplicate page', () => {
-    test('duplicate()', () => {
-      expect(3).toBe(3);
+    let duplicateDescendantsWithStreamSpy;
+
+    jest.mock('../../server/models/serializers/page-serializer');
+    const { serializePageSecurely } = require('../../server/models/serializers/page-serializer');
+    serializePageSecurely.mockImplementation(page => page);
+
+    beforeEach(async(done) => {
+      duplicateDescendantsWithStreamSpy = jest.spyOn(crowi.pageService, 'duplicateDescendantsWithStream').mockImplementation();
+      done();
+    });
+
+    test('duplicate page (isRecursively: false)', async() => {
+      const dummyId = '600d395667536503354c9999';
+      crowi.models.Page.findRelatedTagsById = jest.fn().mockImplementation(() => { return parentTag });
+      const originTagsMock = jest.spyOn(Page, 'findRelatedTagsById').mockImplementation(() => { return parentTag });
+      jest.spyOn(PageTagRelation, 'updatePageTags').mockImplementation(() => { return [dummyId, parentTag.name] });
+      jest.spyOn(PageTagRelation, 'listTagNamesByPage').mockImplementation(() => { return [parentTag.name] });
+
+      const resultPage = await crowi.pageService.duplicate(parentForDuplicate, '/newParentDuplicate', testUser2, false);
+      const duplicatedToPageRevision = await Revision.findOne({ path: '/newParentDuplicate' });
+
+      expect(xssSpy).toHaveBeenCalled();
+      expect(duplicateDescendantsWithStreamSpy).not.toHaveBeenCalled();
+      expect(serializePageSecurely).toHaveBeenCalled();
+      expect(resultPage.path).toBe('/newParentDuplicate');
+      expect(resultPage.lastUpdateUser._id).toEqual(testUser2._id);
+      expect(duplicatedToPageRevision._id).not.toEqual(parentForDuplicate.revision._id);
+      expect(resultPage.grant).toEqual(parentForDuplicate.grant);
+      expect(resultPage.tags).toEqual([originTagsMock().name]);
+
     });
 
     test('duplicateDescendants()', () => {