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

Merge branch 'master' into feature-delete-page

Sotaro KARASAWA 9 лет назад
Родитель
Сommit
1c2217eb36

+ 3 - 3
lib/models/page.js

@@ -325,14 +325,14 @@ module.exports = function(crowi) {
   pageSchema.statics.isCreatableName = function(name) {
     var forbiddenPages = [
       /\^|\$|\*|\+|\#/,
-      /^\/_api\/.*/,
+      /^\/_.*/, // /_api/* and so on
       /^\/\-\/.*/,
       /^\/_r\/.*/,
       /^\/user\/[^\/]+\/(bookmarks|comments|activities|pages|recent-create|recent-edit)/, // reserved
-      /^http:\/\/.+$/, // avoid miss in renaming
+      /^https?:\/\/.+$/, // avoid miss in renaming
       /.+\/edit$/,
       /.+\.md$/,
-      /^\/(installer|register|login|logout|admin|me|files|trash|paste|comments).+/,
+      /^\/(installer|register|login|logout|admin|me|files|trash|paste|comments)(\/.*|$)/,
     ];
 
     var isCreatable = true;

+ 4 - 0
lib/routes/page.js

@@ -59,6 +59,7 @@ module.exports = function(crowi, app) {
     var path = getPathFromRequest(req);
     var limit = 50;
     var offset = parseInt(req.query.offset)  || 0;
+    var SEENER_THRESHOLD = 10;
     path = path + (path == '/' ? '' : '/');
 
     // index page
@@ -90,6 +91,9 @@ module.exports = function(crowi, app) {
 
       pagerOptions.length = pageList.length;
 
+      renderVars.config = {
+        seener_threshold: SEENER_THRESHOLD
+      };
       renderVars.pager = generatePager(pagerOptions);
       renderVars.pages = pageList;
       res.render('page_list', renderVars);

+ 1 - 2
lib/views/layout/layout.html

@@ -49,7 +49,7 @@
   <div class="navbar-header">
     <a class="navbar-brand" href="/">
       <img alt="Crowi" src="/logo/32x32.png" width="16">
-      {% block title %}{{ config.crowi['app:title'] }}{% endblock %}
+      {% block title %}{{ config.crowi['app:title']|default('Crowi') }}{% endblock %}
     </a>
   {% if searchConfigured() %}
   <div class="navbar-form navbar-left search-top visible-lg visible-md" role="search" id="search-top">
@@ -147,4 +147,3 @@
 <script src="/js/app{% if env  == 'production' %}.min{% endif %}.js"></script>
 <script src="/js/crowi{% if env  == 'production' %}.min{% endif %}.js"></script>
 </html>
-

+ 1 - 1
lib/views/page_list.html

@@ -127,7 +127,7 @@
 
     {# list view #}
     <div class="active tab-pane fade page-list-container in" id="view-list">
-      {% include 'widget/page_list.html' with { pages: pages, pager: pager } %}
+      {% include 'widget/page_list.html' with { pages: pages, pager: pager, config: config } %}
     </div>
 
     {# timeline view #}

+ 6 - 0
lib/views/widget/page_list.html

@@ -31,6 +31,12 @@
     </span>
     {% endif  %}
 
+    {% if page.seenUsers.length >= config.seener_threshold %}
+    <span>
+      <i class="fa fa-eye">{{ page.seenUsers.length }}</i>
+    </span>
+    {% endif  %}
+
     {% if !page.isPublic() %}
     <span>
       <i class="fa fa-lock"></i>

+ 38 - 1
test/models/page.test.js

@@ -62,7 +62,7 @@ describe('Page', function () {
         },
       ];
 
-      testDBUtil.generateFixture(conn, 'Page', fixture)
+      return testDBUtil.generateFixture(conn, 'Page', fixture)
       .then(function(pages) {
         done();
       });
@@ -93,6 +93,43 @@ describe('Page', function () {
     });
   });
 
+  describe('.isCreatableName', function() {
+
+    expect(Page.isCreatableName('/hoge')).to.be.true;
+
+    // edge cases
+    expect(Page.isCreatableName('/me')).to.be.false;
+    expect(Page.isCreatableName('/me/')).to.be.false;
+    expect(Page.isCreatableName('/me/x')).to.be.false;
+    expect(Page.isCreatableName('/meeting')).to.be.true;
+    expect(Page.isCreatableName('/meeting/x')).to.be.true;
+
+    // under score
+    expect(Page.isCreatableName('/_')).to.be.false;
+    expect(Page.isCreatableName('/_r/x')).to.be.false;
+    expect(Page.isCreatableName('/_api')).to.be.false;
+    expect(Page.isCreatableName('/_apix')).to.be.false;
+    expect(Page.isCreatableName('/_api/x')).to.be.false;
+
+    expect(Page.isCreatableName('/hoge/xx.md')).to.be.false;
+
+
+    var forbidden = ['installer', 'register', 'login', 'logout', 'admin', 'files', 'trash', 'paste', 'comments'];
+    for (var i = 0; i < forbidden.length ; i++) {
+      var pn = forbidden[i];
+      expect(Page.isCreatableName('/' + pn + '')).to.be.false;
+      expect(Page.isCreatableName('/' + pn + '/')).to.be.false;
+      expect(Page.isCreatableName('/' + pn + '/abc')).to.be.false;
+    }
+
+    var forbidden = ['bookmarks', 'comments', 'activities', 'pages', 'recent-create', 'recent-edit'];
+    for (var i = 0; i < forbidden.length ; i++) {
+      var pn = forbidden[i];
+      expect(Page.isCreatableName('/user/aoi/' + pn)).to.be.false;
+      expect(Page.isCreatableName('/user/aoi/x/' + pn)).to.be.true;
+    }
+  });
+
   describe('.isCreator', function() {
     context('with creator', function() {
       it('should return true', function(done) {