concen 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +10 -0
- data/Gemfile +23 -0
- data/Gemfile.lock +143 -0
- data/README.md +41 -0
- data/Rakefile +28 -0
- data/app/stylesheets/partials/.sass +21 -0
- data/concen.gemspec +33 -0
- data/config/initializers/notification.rb +8 -0
- data/config/initializers/prepend_routing_paths.rb +6 -0
- data/lib/concen/version.rb +1 -1
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +44 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +26 -0
- data/test/dummy/config/environments/production.rb +49 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/mongoid.yml +23 -0
- data/test/dummy/config/routes.rb +58 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/javascripts/application.js +2 -0
- data/test/dummy/public/javascripts/controls.js +965 -0
- data/test/dummy/public/javascripts/dragdrop.js +974 -0
- data/test/dummy/public/javascripts/effects.js +1123 -0
- data/test/dummy/public/javascripts/prototype.js +6001 -0
- data/test/dummy/public/javascripts/rails.js +175 -0
- data/test/dummy/public/stylesheets/.gitkeep +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/fabricators.rb +12 -0
- data/test/integration/navigation_test.rb +7 -0
- data/test/support/integration_case.rb +5 -0
- data/test/support/raw_text/code_blocks.html +12 -0
- data/test/support/raw_text/code_blocks.txt +19 -0
- data/test/support/raw_text/multi_content.html +2 -0
- data/test/support/raw_text/multi_content.txt +17 -0
- data/test/support/raw_text/smartypants.html +3 -0
- data/test/support/raw_text/smartypants.txt +11 -0
- data/test/support/raw_text/smartypants_escape.html +1 -0
- data/test/support/raw_text/smartypants_escape.txt +9 -0
- data/test/test_helper.rb +26 -0
- data/test/unit/concen_test.rb +7 -0
- data/test/unit/grid_file_test.rb +41 -0
- data/test/unit/page_test.rb +95 -0
- data/test/unit/user_test.rb +42 -0
- metadata +139 -36
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
(function() {
|
|
2
|
+
// Technique from Juriy Zaytsev
|
|
3
|
+
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
|
|
4
|
+
function isEventSupported(eventName) {
|
|
5
|
+
var el = document.createElement('div');
|
|
6
|
+
eventName = 'on' + eventName;
|
|
7
|
+
var isSupported = (eventName in el);
|
|
8
|
+
if (!isSupported) {
|
|
9
|
+
el.setAttribute(eventName, 'return;');
|
|
10
|
+
isSupported = typeof el[eventName] == 'function';
|
|
11
|
+
}
|
|
12
|
+
el = null;
|
|
13
|
+
return isSupported;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function isForm(element) {
|
|
17
|
+
return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isInput(element) {
|
|
21
|
+
if (Object.isElement(element)) {
|
|
22
|
+
var name = element.nodeName.toUpperCase()
|
|
23
|
+
return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
|
|
24
|
+
}
|
|
25
|
+
else return false
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
var submitBubbles = isEventSupported('submit'),
|
|
29
|
+
changeBubbles = isEventSupported('change')
|
|
30
|
+
|
|
31
|
+
if (!submitBubbles || !changeBubbles) {
|
|
32
|
+
// augment the Event.Handler class to observe custom events when needed
|
|
33
|
+
Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
|
|
34
|
+
function(init, element, eventName, selector, callback) {
|
|
35
|
+
init(element, eventName, selector, callback)
|
|
36
|
+
// is the handler being attached to an element that doesn't support this event?
|
|
37
|
+
if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
|
|
38
|
+
(!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
|
|
39
|
+
// "submit" => "emulated:submit"
|
|
40
|
+
this.eventName = 'emulated:' + this.eventName
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
)
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (!submitBubbles) {
|
|
47
|
+
// discover forms on the page by observing focus events which always bubble
|
|
48
|
+
document.on('focusin', 'form', function(focusEvent, form) {
|
|
49
|
+
// special handler for the real "submit" event (one-time operation)
|
|
50
|
+
if (!form.retrieve('emulated:submit')) {
|
|
51
|
+
form.on('submit', function(submitEvent) {
|
|
52
|
+
var emulated = form.fire('emulated:submit', submitEvent, true)
|
|
53
|
+
// if custom event received preventDefault, cancel the real one too
|
|
54
|
+
if (emulated.returnValue === false) submitEvent.preventDefault()
|
|
55
|
+
})
|
|
56
|
+
form.store('emulated:submit', true)
|
|
57
|
+
}
|
|
58
|
+
})
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (!changeBubbles) {
|
|
62
|
+
// discover form inputs on the page
|
|
63
|
+
document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
|
|
64
|
+
// special handler for real "change" events
|
|
65
|
+
if (!input.retrieve('emulated:change')) {
|
|
66
|
+
input.on('change', function(changeEvent) {
|
|
67
|
+
input.fire('emulated:change', changeEvent, true)
|
|
68
|
+
})
|
|
69
|
+
input.store('emulated:change', true)
|
|
70
|
+
}
|
|
71
|
+
})
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function handleRemote(element) {
|
|
75
|
+
var method, url, params;
|
|
76
|
+
|
|
77
|
+
var event = element.fire("ajax:before");
|
|
78
|
+
if (event.stopped) return false;
|
|
79
|
+
|
|
80
|
+
if (element.tagName.toLowerCase() === 'form') {
|
|
81
|
+
method = element.readAttribute('method') || 'post';
|
|
82
|
+
url = element.readAttribute('action');
|
|
83
|
+
params = element.serialize();
|
|
84
|
+
} else {
|
|
85
|
+
method = element.readAttribute('data-method') || 'get';
|
|
86
|
+
url = element.readAttribute('href');
|
|
87
|
+
params = {};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
new Ajax.Request(url, {
|
|
91
|
+
method: method,
|
|
92
|
+
parameters: params,
|
|
93
|
+
evalScripts: true,
|
|
94
|
+
|
|
95
|
+
onComplete: function(request) { element.fire("ajax:complete", request); },
|
|
96
|
+
onSuccess: function(request) { element.fire("ajax:success", request); },
|
|
97
|
+
onFailure: function(request) { element.fire("ajax:failure", request); }
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
element.fire("ajax:after");
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function handleMethod(element) {
|
|
104
|
+
var method = element.readAttribute('data-method'),
|
|
105
|
+
url = element.readAttribute('href'),
|
|
106
|
+
csrf_param = $$('meta[name=csrf-param]')[0],
|
|
107
|
+
csrf_token = $$('meta[name=csrf-token]')[0];
|
|
108
|
+
|
|
109
|
+
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
|
|
110
|
+
element.parentNode.insert(form);
|
|
111
|
+
|
|
112
|
+
if (method !== 'post') {
|
|
113
|
+
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
|
114
|
+
form.insert(field);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (csrf_param) {
|
|
118
|
+
var param = csrf_param.readAttribute('content'),
|
|
119
|
+
token = csrf_token.readAttribute('content'),
|
|
120
|
+
field = new Element('input', { type: 'hidden', name: param, value: token });
|
|
121
|
+
form.insert(field);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
form.submit();
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
document.on("click", "*[data-confirm]", function(event, element) {
|
|
129
|
+
var message = element.readAttribute('data-confirm');
|
|
130
|
+
if (!confirm(message)) event.stop();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
document.on("click", "a[data-remote]", function(event, element) {
|
|
134
|
+
if (event.stopped) return;
|
|
135
|
+
handleRemote(element);
|
|
136
|
+
event.stop();
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
document.on("click", "a[data-method]", function(event, element) {
|
|
140
|
+
if (event.stopped) return;
|
|
141
|
+
handleMethod(element);
|
|
142
|
+
event.stop();
|
|
143
|
+
});
|
|
144
|
+
|
|
145
|
+
document.on("submit", function(event) {
|
|
146
|
+
var element = event.findElement(),
|
|
147
|
+
message = element.readAttribute('data-confirm');
|
|
148
|
+
if (message && !confirm(message)) {
|
|
149
|
+
event.stop();
|
|
150
|
+
return false;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
var inputs = element.select("input[type=submit][data-disable-with]");
|
|
154
|
+
inputs.each(function(input) {
|
|
155
|
+
input.disabled = true;
|
|
156
|
+
input.writeAttribute('data-original-value', input.value);
|
|
157
|
+
input.value = input.readAttribute('data-disable-with');
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
var element = event.findElement("form[data-remote]");
|
|
161
|
+
if (element) {
|
|
162
|
+
handleRemote(element);
|
|
163
|
+
event.stop();
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
document.on("ajax:after", "form", function(event, element) {
|
|
168
|
+
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
|
169
|
+
inputs.each(function(input) {
|
|
170
|
+
input.value = input.readAttribute('data-original-value');
|
|
171
|
+
input.removeAttribute('data-original-value');
|
|
172
|
+
input.disabled = false;
|
|
173
|
+
});
|
|
174
|
+
});
|
|
175
|
+
})();
|
|
File without changes
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
|
3
|
+
|
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
|
6
|
+
require 'rails/commands'
|
data/test/fabricators.rb
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Fabricator("concen/user") do
|
|
2
|
+
username { Fabricate.sequence(:username) { |i| "username#{i}" } }
|
|
3
|
+
full_name { Fabricate.sequence(:full_name) { |i| "Full Name #{i}" } }
|
|
4
|
+
email { Fabricate.sequence(:email) { |i| "user#{i}@mail.com" } }
|
|
5
|
+
password "thisismypassword"
|
|
6
|
+
password_confirmation "thisismypassword"
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
Fabricator("concen/page") do
|
|
10
|
+
title { Fabricate.sequence(:title) { |i| "Title #{i}" } }
|
|
11
|
+
end
|
|
12
|
+
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<p>Haml makes it very easy to include text in various formats such as CSS, JavaScript, Markdown or Textile. Specifically for Markdown, Haml depends on additional Ruby Gem such as RDiscount, peg-markdown, or Maruku. Recently, there is a new Ruby Gem for Markdown parser called <a href="https://github.com/tanoku/redcarpet">Redcarpet</a>, created by <a href="https://github.com/tanoku">Vicent Martí</a>.</p>
|
|
2
|
+
|
|
3
|
+
<p>Redcarpet is basically a Ruby wrapper of <a href="https://github.com/tanoku/redcarpet">Upskirt</a>, which originally created by Natacha Porté. Upskirt is a standard compliant Markdown parser and it supports many extensions such as non-strict emphasis, fenced code blocks, tables, and autolinks. One of the best features of Upskirt is that it handles arbitrary and malicious input text very well.</p>
|
|
4
|
+
|
|
5
|
+
<blockquote>
|
|
6
|
+
<p>Upskirt has been extensively security audited, and includes protection against all possible DOS attacks (stack overflows, out of memory situations, malformed Markdown syntax…) and against client attacks through malicious embedded HTML.</p>
|
|
7
|
+
</blockquote>
|
|
8
|
+
|
|
9
|
+
<p>To integrate Rercarpet and Haml in your Rails app, first add the Redcarpet gem in the <code>Gemfile</code>.</p>
|
|
10
|
+
|
|
11
|
+
<pre><code>gem "redcarpet", "~> 1.17.2"
|
|
12
|
+
</code></pre>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
Title: Use Redcarpet as a Markdown Filter for Haml in Rails
|
|
2
|
+
|
|
3
|
+
Description: Haml by default does not use Redcarpet Ruby Gem if available as the dependecy to parse Markdown text format. But it’s easy to overwrite the Haml internal to use Redcarpet.
|
|
4
|
+
|
|
5
|
+
Publish Time: 2011-07-16 19:00:00 +0800
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
Haml makes it very easy to include text in various formats such as CSS, JavaScript, Markdown or Textile. Specifically for Markdown, Haml depends on additional Ruby Gem such as RDiscount, peg-markdown, or Maruku. Recently, there is a new Ruby Gem for Markdown parser called [Redcarpet](https://github.com/tanoku/redcarpet), created by [Vicent Martí](https://github.com/tanoku).
|
|
10
|
+
|
|
11
|
+
Redcarpet is basically a Ruby wrapper of [Upskirt](https://github.com/tanoku/redcarpet), which originally created by Natacha Porté. Upskirt is a standard compliant Markdown parser and it supports many extensions such as non-strict emphasis, fenced code blocks, tables, and autolinks. One of the best features of Upskirt is that it handles arbitrary and malicious input text very well.
|
|
12
|
+
|
|
13
|
+
> Upskirt has been extensively security audited, and includes protection against all possible DOS attacks (stack overflows, out of memory situations, malformed Markdown syntax...) and against client attacks through malicious embedded HTML.
|
|
14
|
+
|
|
15
|
+
To integrate Rercarpet and Haml in your Rails app, first add the Redcarpet gem in the `Gemfile`.
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
gem "redcarpet", "~> 1.17.2"
|
|
19
|
+
```
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
<p>Suddenly he began writing in sheer panic, only imperfectly aware of what he was setting down. His small but childish handwriting straggled up and down the page, shedding first its capital letters and finally even its full stops:</p>
|
|
2
|
+
<p>April 4th, 1984. Last night to the flicks. All war films. One very good one of a ship full of refugees being bombed somewhere in the Mediterranean. Audience much amused by shots of a great huge fat man trying to swim away with a helicopter after him, first you saw him wallowing along in the water like a porpoise, then you saw him through the helicopters gunsights, then he was full of holes and the sea round him turned pink and he sank as suddenly as though the holes had let in the water, audience shouting with laughter when he sank.</p>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Title: 1984 — Chapter 3
|
|
2
|
+
|
|
3
|
+
Description: Nineteen Eighty-Four (sometimes written 1984) is a 1948 dystopian fiction written by George Orwell about a society ruled by an oligarchical dictatorship.
|
|
4
|
+
|
|
5
|
+
Publish Time: 2011-07-22 02:28:53 +0800
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
@ Part 1
|
|
10
|
+
|
|
11
|
+
Suddenly he began writing in sheer panic, only imperfectly aware of what he was setting down. His small but childish handwriting straggled up and down the page, shedding first its capital letters and finally even its full stops:
|
|
12
|
+
|
|
13
|
+
-----
|
|
14
|
+
|
|
15
|
+
@ Part 2
|
|
16
|
+
|
|
17
|
+
April 4th, 1984. Last night to the flicks. All war films. One very good one of a ship full of refugees being bombed somewhere in the Mediterranean. Audience much amused by shots of a great huge fat man trying to swim away with a helicopter after him, first you saw him wallowing along in the water like a porpoise, then you saw him through the helicopters gunsights, then he was full of holes and the sea round him turned pink and he sank as suddenly as though the holes had let in the water, audience shouting with laughter when he sank.
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
<p>He sat back. A sense of complete helplessness had descended upon him. To begin with, he did not know with any certainty that this was 1984. It must be round about that date, since he was “fairly” sure that his age was thirty-nine, and he ‘believed’ that he had been born in 1944–1945; but it was never possible nowadays to pin down any date within a year or two.</p>
|
|
2
|
+
|
|
3
|
+
<p>For whom, it suddenly occurred to him to wonder, was he writing this diary? For the future, for the unborn. His mind hovered — for a moment round the doubtful date on the page, and then fetched up with a bump against the Newspeak word doublethink. For the first time the magnitude of what he had undertaken came home to him. How could you communicate with the future? It was of its nature impossible. Either the future would resemble the present, in which case it would not listen to him: or it would be different from it, and his predicament would be meaningless…</p>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
Title: 1984 — Chapter 1
|
|
2
|
+
|
|
3
|
+
Description: Nineteen Eighty-Four (sometimes written 1984) is a 1948 dystopian fiction written by George Orwell about a society ruled by an oligarchical dictatorship.
|
|
4
|
+
|
|
5
|
+
Publish Time: 2011-07-22 02:28:53 +0800
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
He sat back. A sense of complete helplessness had descended upon him. To begin with, he did not know with any certainty that this was 1984. It must be round about that date, since he was "fairly" sure that his age was thirty-nine, and he 'believed' that he had been born in 1944--1945; but it was never possible nowadays to pin down any date within a year or two.
|
|
10
|
+
|
|
11
|
+
For whom, it suddenly occurred to him to wonder, was he writing this diary? For the future, for the unborn. His mind hovered --- for a moment round the doubtful date on the page, and then fetched up with a bump against the Newspeak word doublethink. For the first time the magnitude of what he had undertaken came home to him. How could you communicate with the future? It was of its nature impossible. Either the future would resemble the present, in which case it would not listen to him: or it would be different from it, and his predicament would be meaningless...
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<p>For some time he sat gazing stupidly at the paper. The telescreen' had changed over to strident military music. It was curious that he seemed not merely to have lost the power of expressing himself, but even to have forgotten what it was that he had originally intended to say. For weeks past he had been making ready for this moment, and it had never crossed his mind that anything would be needed except courage. The actual writing would be easy. All he had to do was to transfer to paper the interminable restless monologue that had been running inside his head, literally for years. At this moment, however, even the monologue had dried up. Moreover his varicose ulcer had begun itching unbearably. He dared not scratch it, because if he did so it always became inflamed. The seconds were ticking by. He was conscious of nothing except the blankness of the page in front of him, the itching of the skin above his ankle, the blaring of the music, and a slight booziness caused by the gin.</p>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Title: 1984 — Chapter 2
|
|
2
|
+
|
|
3
|
+
Description: Nineteen Eighty-Four (sometimes written 1984) is a 1948 dystopian fiction written by George Orwell about a society ruled by an oligarchical dictatorship.
|
|
4
|
+
|
|
5
|
+
Publish Time: 2011-07-22 02:28:53 +0800
|
|
6
|
+
|
|
7
|
+
-----
|
|
8
|
+
|
|
9
|
+
For some time he sat gazing stupidly at the paper. The telescreen\' had changed over to strident military music. It was curious that he seemed not merely to have lost the power of expressing himself, but even to have forgotten what it was that he had originally intended to say. For weeks past he had been making ready for this moment, and it had never crossed his mind that anything would be needed except courage. The actual writing would be easy. All he had to do was to transfer to paper the interminable restless monologue that had been running inside his head, literally for years. At this moment, however, even the monologue had dried up. Moreover his varicose ulcer had begun itching unbearably. He dared not scratch it, because if he did so it always became inflamed. The seconds were ticking by. He was conscious of nothing except the blankness of the page in front of him, the itching of the skin above his ankle, the blaring of the music, and a slight booziness caused by the gin.
|
data/test/test_helper.rb
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# Configure Rails Envinronment
|
|
2
|
+
ENV["RAILS_ENV"] = "test"
|
|
3
|
+
|
|
4
|
+
require File.expand_path("../dummy/config/environment.rb", __FILE__)
|
|
5
|
+
require File.expand_path("../fabricators.rb", __FILE__)
|
|
6
|
+
require "rails/test_help"
|
|
7
|
+
require "database_cleaner"
|
|
8
|
+
require "turn"
|
|
9
|
+
|
|
10
|
+
ActionMailer::Base.delivery_method = :test
|
|
11
|
+
ActionMailer::Base.perform_deliveries = true
|
|
12
|
+
ActionMailer::Base.default_url_options[:host] = "test.com"
|
|
13
|
+
|
|
14
|
+
Rails.backtrace_cleaner.remove_silencers!
|
|
15
|
+
|
|
16
|
+
# Configure capybara for integration testing
|
|
17
|
+
# require "capybara/rails"
|
|
18
|
+
# Capybara.default_driver = :rack_test
|
|
19
|
+
# Capybara.default_selector = :css
|
|
20
|
+
|
|
21
|
+
# Load support files
|
|
22
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
|
23
|
+
|
|
24
|
+
# Clean database.
|
|
25
|
+
DatabaseCleaner.strategy = :truncation
|
|
26
|
+
DatabaseCleaner.clean
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class GridFileTest < ActiveSupport::TestCase
|
|
4
|
+
test "should store file in GridFS" do
|
|
5
|
+
page = Fabricate "concen/page"
|
|
6
|
+
grid_file = page.grid_files.build
|
|
7
|
+
grid_file.store File.read("#{Rails.root}/public/404.html"), "404.html"
|
|
8
|
+
assert_equal grid_file.read, File.read("#{Rails.root}/public/404.html")
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
test "should delete file from GridFS when page is deleted" do
|
|
12
|
+
page = Fabricate "concen/page"
|
|
13
|
+
grid_file = page.grid_files.build
|
|
14
|
+
grid_file.store File.read("#{Rails.root}/public/404.html"), "404.html"
|
|
15
|
+
grid_id = grid_file.grid_id.dup
|
|
16
|
+
page.destroy
|
|
17
|
+
grid = Mongo::Grid.new Mongoid.database
|
|
18
|
+
assert_raise(Mongo::GridFileNotFound) { grid.get(grid_id).read }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test "should delete associated grid_file when page is deleted" do
|
|
22
|
+
page = Fabricate "concen/page"
|
|
23
|
+
grid_file = page.grid_files.build
|
|
24
|
+
grid_file.store File.read("#{Rails.root}/public/404.html"), "404.html"
|
|
25
|
+
page.destroy
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "should store correct original_filename" do
|
|
29
|
+
page = Fabricate "concen/page"
|
|
30
|
+
grid_file = page.grid_files.build
|
|
31
|
+
grid_file.store File.read("#{Rails.root}/public/404.html"), "404.html"
|
|
32
|
+
assert_equal grid_file.original_filename, "404.html"
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
test "should include id in filename" do
|
|
36
|
+
page = Fabricate "concen/page"
|
|
37
|
+
grid_file = page.grid_files.build
|
|
38
|
+
grid_file.store File.read("#{Rails.root}/public/404.html"), "404.html"
|
|
39
|
+
assert grid_file.filename.include?(grid_file.id.to_s), "Filename does not include grid_file id."
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require "test_helper"
|
|
2
|
+
|
|
3
|
+
class PageTest < ActiveSupport::TestCase
|
|
4
|
+
test "should create page" do
|
|
5
|
+
page = Fabricate "concen/page"
|
|
6
|
+
assert_not_nil page.id
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
test "should create child page" do
|
|
10
|
+
page = Fabricate "concen/page"
|
|
11
|
+
child_page = page.children.create :title => "1984"
|
|
12
|
+
assert_not_nil child_page.id
|
|
13
|
+
assert_equal page.id, child_page.parent.id
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
test "should parse title from raw_text" do
|
|
17
|
+
page = Fabricate "concen/page", :title => nil, :raw_text => "Title: Page Title"
|
|
18
|
+
assert_equal page.title, "Page Title"
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
test "should parse publish_time from raw_text" do
|
|
22
|
+
raw_text = "Title: Page Title 2\n\nPublish Time: now"
|
|
23
|
+
page = Fabricate "concen/page", :title => nil, :raw_text => raw_text
|
|
24
|
+
assert_not_nil page.publish_time
|
|
25
|
+
assert_not_equal page.raw_text, raw_text
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
test "should parse multi content from raw_text and conver to html correctly" do
|
|
29
|
+
raw_text = File.read "#{File.dirname(__FILE__)}/../support/raw_text/multi_content.txt"
|
|
30
|
+
html = File.read("#{File.dirname(__FILE__)}/../support/raw_text/multi_content.html")
|
|
31
|
+
page = Fabricate "concen/page", :title => nil, :raw_text => raw_text
|
|
32
|
+
assert_not_nil page.content
|
|
33
|
+
assert_equal page.content.keys, ["part_1", "part_2"]
|
|
34
|
+
assert_not_nil page.content_in_html("part_1")
|
|
35
|
+
assert_not_nil page.content_in_html("part_2")
|
|
36
|
+
assert_equal page.content_in_html("part_1") + page.content_in_html("part_2"), html
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
test "should parse content with SmartyPants supported entities and convert to html correctly" do
|
|
40
|
+
raw_text_smartypants = File.read "#{File.dirname(__FILE__)}/../support/raw_text/smartypants.txt"
|
|
41
|
+
raw_text_smartypants_escape = File.read "#{File.dirname(__FILE__)}/../support/raw_text/smartypants_escape.txt"
|
|
42
|
+
assert_not_nil raw_text_smartypants
|
|
43
|
+
assert_not_nil raw_text_smartypants_escape
|
|
44
|
+
|
|
45
|
+
page1 = Fabricate "concen/page", :title => nil, :raw_text => raw_text_smartypants
|
|
46
|
+
assert_equal page1.content_in_html, page1.content_in_html("main")
|
|
47
|
+
assert_equal page1.content_in_html, File.read("#{File.dirname(__FILE__)}/../support/raw_text/smartypants.html")
|
|
48
|
+
|
|
49
|
+
page2 = Fabricate "concen/page", :title => nil, :raw_text => raw_text_smartypants_escape
|
|
50
|
+
assert_equal page2.content_in_html, page2.content_in_html("main")
|
|
51
|
+
assert_equal page2.content_in_html, File.read("#{File.dirname(__FILE__)}/../support/raw_text/smartypants_escape.html")
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
test "should parse content with code blocks and convert to html correctly" do
|
|
55
|
+
raw_text_code_blocks = File.read "#{File.dirname(__FILE__)}/../support/raw_text/code_blocks.txt"
|
|
56
|
+
assert_not_nil raw_text_code_blocks
|
|
57
|
+
|
|
58
|
+
page = Fabricate "concen/page", :title => nil, :raw_text => raw_text_code_blocks
|
|
59
|
+
assert_equal page.content_in_html, page.content_in_html("main")
|
|
60
|
+
assert_equal page.content_in_html, File.read("#{File.dirname(__FILE__)}/../support/raw_text/code_blocks.html")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
test "should have default_slug" do
|
|
64
|
+
page = Fabricate "concen/page"
|
|
65
|
+
assert_not_nil page.default_slug
|
|
66
|
+
assert page.default_slug.length > 0
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
test "should not be created without title" do
|
|
70
|
+
page = Fabricate.build "concen/page", :title => nil
|
|
71
|
+
assert_raise(Mongoid::Errors::Validations) { page.save! }
|
|
72
|
+
assert_equal page.errors[:title].first, "can't be blank"
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
test "should have authors" do
|
|
76
|
+
page = Fabricate.build "concen/page", :authors => ["user1", "user2", "user3"]
|
|
77
|
+
assert_equal page.authors.count, 3
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
test "should get correct author_as_user" do
|
|
81
|
+
user = Fabricate "concen/user"
|
|
82
|
+
page = Fabricate.build "concen/page", :authors => [user.username, "user2"]
|
|
83
|
+
assert_equal page.authors.count, 2
|
|
84
|
+
assert_equal page.authors_as_user.count, 1
|
|
85
|
+
assert page.authors_as_user.include?(user.reload), "Does not include a correct user."
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
test "should get the correct slug" do
|
|
89
|
+
page = Fabricate "concen/page", :title => "New Title"
|
|
90
|
+
assert_equal page.slug, "new-title"
|
|
91
|
+
page.write_attribute :slug, "new-slug"
|
|
92
|
+
page.save
|
|
93
|
+
assert_equal page.slug, "new-slug"
|
|
94
|
+
end
|
|
95
|
+
end
|