mumuki-laboratory 7.7.6 → 7.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +13 -3
- data/Rakefile +7 -1
- data/app/assets/javascripts/mumuki_laboratory/application/alias-modes.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/bridge.js +66 -57
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror-builder.js +28 -25
- data/app/assets/javascripts/mumuki_laboratory/application/codemirror.js +8 -10
- data/app/assets/javascripts/mumuki_laboratory/application/confirmation.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/console.js +41 -43
- data/app/assets/javascripts/mumuki_laboratory/application/csrf-token.js +9 -12
- data/app/assets/javascripts/mumuki_laboratory/application/custom-editor.js +11 -15
- data/app/assets/javascripts/mumuki_laboratory/application/discussions.js +1 -3
- data/app/assets/javascripts/mumuki_laboratory/application/editors.js +104 -0
- data/app/assets/javascripts/mumuki_laboratory/application/elipsis.js +5 -4
- data/app/assets/javascripts/mumuki_laboratory/application/exercise.js +32 -0
- data/app/assets/javascripts/mumuki_laboratory/application/inputs.js +4 -2
- data/app/assets/javascripts/mumuki_laboratory/application/interval.js +2 -4
- data/app/assets/javascripts/mumuki_laboratory/application/kids.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/load-analytics.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/load-error-svg.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/messages.js +2 -2
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-choice.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/multiple-scenarios.js +3 -6
- data/app/assets/javascripts/mumuki_laboratory/application/pin.js +3 -5
- data/app/assets/javascripts/mumuki_laboratory/application/progress.js +24 -6
- data/app/assets/javascripts/mumuki_laboratory/application/results-renderer.js +20 -11
- data/app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js +12 -5
- data/app/assets/javascripts/mumuki_laboratory/application/submission.js +19 -101
- data/app/assets/javascripts/mumuki_laboratory/application/submissions-store.js +93 -0
- data/app/assets/javascripts/mumuki_laboratory/application/sync-mode.js +75 -0
- data/app/assets/javascripts/mumuki_laboratory/application/timer.js +5 -6
- data/app/assets/javascripts/mumuki_laboratory/application/tooltip.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/upload.js +1 -1
- data/app/assets/javascripts/mumuki_laboratory/application/user.js +1 -1
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_gs-board.scss +3 -0
- data/app/assets/stylesheets/mumuki_laboratory/application/modules/_kids.scss +0 -1
- data/app/controllers/application_controller.rb +1 -0
- data/app/helpers/{locale_helper.rb → globals_helper.rb} +6 -2
- data/app/mailers/user_mailer.rb +24 -11
- data/app/views/book/show.html.erb +1 -1
- data/app/views/exercises/show.html.erb +2 -0
- data/app/views/layouts/_main.html.erb +1 -2
- data/app/views/layouts/_progress.html.erb +1 -1
- data/app/views/layouts/_progress_bar.html.erb +7 -1
- data/app/views/layouts/application.html.erb +1 -1
- data/lib/mumuki/laboratory/controllers.rb +1 -0
- data/lib/mumuki/laboratory/controllers/incognito_mode.rb +28 -0
- data/lib/mumuki/laboratory/locales/en.yml +6 -4
- data/lib/mumuki/laboratory/locales/es.yml +6 -4
- data/lib/mumuki/laboratory/locales/pt.yml +4 -2
- data/lib/mumuki/laboratory/version.rb +1 -1
- data/spec/dummy/db/schema.rb +2 -1
- data/spec/features/chapter_spec.rb +17 -0
- data/spec/features/exercise_flow_spec.rb +47 -2
- data/spec/features/home_public_flow_spec.rb +16 -0
- data/spec/javascripts/editors-spec.js +54 -0
- data/spec/javascripts/exercise-spec.js +22 -0
- data/spec/javascripts/global-spec.js +6 -0
- data/spec/javascripts/spec-helper.js +4 -0
- data/spec/javascripts/submissions-store-spec.js +44 -0
- data/spec/javascripts/sync-mode-spec.js +15 -0
- data/spec/mailers/user_mailer_spec.rb +18 -3
- data/spec/teaspoon_env.rb +8 -2
- data/vendor/assets/javascripts/codemirror-modes/gobstones.js +2 -3
- metadata +19 -5
- data/app/helpers/version_helper.rb +0 -5
@@ -0,0 +1,54 @@
|
|
1
|
+
describe('editors', () => {
|
2
|
+
|
3
|
+
beforeEach(() => {
|
4
|
+
mumuki.CustomEditor.clearSources()
|
5
|
+
})
|
6
|
+
|
7
|
+
it('has initially no sources', () => {
|
8
|
+
expect(mumuki.CustomEditor.hasSources).toBe(false)
|
9
|
+
});
|
10
|
+
|
11
|
+
it('can add a custom source', () => {
|
12
|
+
mumuki.editors.addCustomSource({
|
13
|
+
getContent() {
|
14
|
+
return { name: "solution[content]", value: 'the value' } ;
|
15
|
+
}
|
16
|
+
});
|
17
|
+
|
18
|
+
expect(mumuki.CustomEditor.hasSources).toBe(true);
|
19
|
+
expect(mumuki.CustomEditor.getContents()[0].value).toEqual('the value');
|
20
|
+
expect(mumuki.CustomEditor.getContents()[0].name).toEqual('solution[content]');
|
21
|
+
});
|
22
|
+
|
23
|
+
it('reads the custom sources if present, ignoring the form', () => {
|
24
|
+
$('body').html(`
|
25
|
+
<form role="form" class="new_solution">
|
26
|
+
<div class="field form-group editor-code">
|
27
|
+
<textarea class="form-control editor" name="solution[content]" id="solution_content">the standard solution</textarea>
|
28
|
+
</div>
|
29
|
+
</form>`)
|
30
|
+
|
31
|
+
mumuki.editors.addCustomSource({
|
32
|
+
getContent() {
|
33
|
+
return { name: "solution[content]", value: 'the custom solution' } ;
|
34
|
+
}
|
35
|
+
});
|
36
|
+
|
37
|
+
expect(mumuki.editors.getSubmission()).toEqual({"solution[content]":"the custom solution"});
|
38
|
+
});
|
39
|
+
|
40
|
+
it('reads the form if no sources', () => {
|
41
|
+
$('body').html(`
|
42
|
+
<form role="form" class="new_solution">
|
43
|
+
<div class="field form-group editor-code">
|
44
|
+
<textarea class="form-control editor" name="solution[content]" id="solution_content">the solution</textarea>
|
45
|
+
</div>
|
46
|
+
</form>`)
|
47
|
+
expect(mumuki.editors.getSubmission()).toEqual({"solution[content]":"the solution"});
|
48
|
+
});
|
49
|
+
|
50
|
+
it('produces empty submission if no form nor sources', () => {
|
51
|
+
$('body').html(``);
|
52
|
+
expect(mumuki.editors.getSubmission()).toEqual({});
|
53
|
+
});
|
54
|
+
})
|
@@ -0,0 +1,22 @@
|
|
1
|
+
describe('exercise', () => {
|
2
|
+
it('current exercise information is available when present', () => {
|
3
|
+
$('body').html(`
|
4
|
+
<input type="hidden" name="mu-exercise-id" id="mu-exercise-id" value="3361" />
|
5
|
+
<input type="hidden" name="mu-exercise-layout" id="mu-exercise-layout" value="input_right" />`)
|
6
|
+
|
7
|
+
mumuki.exercise.load()
|
8
|
+
|
9
|
+
expect(mumuki.exercise.id).toBe(3361);
|
10
|
+
expect(mumuki.exercise.layout).toBe('input_right');
|
11
|
+
})
|
12
|
+
|
13
|
+
it('current exercise information is available when not present', () => {
|
14
|
+
$('body').html(``)
|
15
|
+
|
16
|
+
mumuki.exercise.load()
|
17
|
+
|
18
|
+
expect(mumuki.exercise.id).toBe(null);
|
19
|
+
expect(mumuki.exercise.layout).toBe(null);
|
20
|
+
})
|
21
|
+
|
22
|
+
})
|
@@ -0,0 +1,44 @@
|
|
1
|
+
describe("SubmissionsStore", () => {
|
2
|
+
const emptyProgramSubmission = {"solution[content]": "program {}"};
|
3
|
+
/** @type {SubmissionResult} */
|
4
|
+
const passedSubmissionResult = {status: 'passed'};
|
5
|
+
/** @type {SubmissionAndResult} */
|
6
|
+
const passedEmptyProgramSubmissionAndResult = { submission: emptyProgramSubmission, result: passedSubmissionResult };
|
7
|
+
|
8
|
+
beforeEach(() => {
|
9
|
+
window.localStorage.clear()
|
10
|
+
});
|
11
|
+
|
12
|
+
describe('getLastSubmission', () => {
|
13
|
+
it("answers null if submission not present", () => {
|
14
|
+
expect(mumuki.SubmissionsStore.getLastSubmissionAndResult(1)).toBe(null)
|
15
|
+
})
|
16
|
+
|
17
|
+
it("answers the last submission result if already sent", () => {
|
18
|
+
mumuki.SubmissionsStore.setSubmissionResultFor(1, passedEmptyProgramSubmissionAndResult)
|
19
|
+
expect(mumuki.SubmissionsStore.getLastSubmissionAndResult(1)).toEqual(passedEmptyProgramSubmissionAndResult)
|
20
|
+
})
|
21
|
+
})
|
22
|
+
|
23
|
+
describe('getLastSubmissionStatus', () => {
|
24
|
+
it("answers pending if submission not present", () => {
|
25
|
+
expect(mumuki.SubmissionsStore.getLastSubmissionStatus(1)).toBe('pending')
|
26
|
+
})
|
27
|
+
|
28
|
+
it("answers the last submission status if previously sent", () => {
|
29
|
+
mumuki.SubmissionsStore.setSubmissionResultFor(1, passedEmptyProgramSubmissionAndResult)
|
30
|
+
expect(mumuki.SubmissionsStore.getLastSubmissionStatus(1)).toBe('passed')
|
31
|
+
})
|
32
|
+
});
|
33
|
+
|
34
|
+
describe('getCachedResultFor', () => {
|
35
|
+
it("answers null if submission not present", () => {
|
36
|
+
expect(mumuki.SubmissionsStore.getSubmissionResultFor(1, emptyProgramSubmission)).toBe(null)
|
37
|
+
})
|
38
|
+
|
39
|
+
it("answers the last submission if previously sent", () => {
|
40
|
+
mumuki.SubmissionsStore.setSubmissionResultFor(1, passedEmptyProgramSubmissionAndResult)
|
41
|
+
expect(mumuki.SubmissionsStore.getSubmissionResultFor(1, emptyProgramSubmission)).toEqual(passedSubmissionResult)
|
42
|
+
})
|
43
|
+
});
|
44
|
+
})
|
@@ -0,0 +1,15 @@
|
|
1
|
+
describe('sync mode', () => {
|
2
|
+
it('can choose server mode', () => {
|
3
|
+
mumuki.incognitoUser = false;
|
4
|
+
mumuki.syncMode._selectSyncMode();
|
5
|
+
|
6
|
+
expect(mumuki.syncMode._current instanceof mumuki.syncMode.ServerSyncMode).toBe(true);
|
7
|
+
})
|
8
|
+
|
9
|
+
it('can choose local mode', () => {
|
10
|
+
mumuki.incognitoUser = true;
|
11
|
+
mumuki.syncMode._selectSyncMode();
|
12
|
+
|
13
|
+
expect(mumuki.syncMode._current instanceof mumuki.syncMode.ClientSyncMode).toBe(true);
|
14
|
+
})
|
15
|
+
})
|
@@ -148,21 +148,21 @@ RSpec.describe UserMailer, type: :mailer do
|
|
148
148
|
|
149
149
|
context "registered 1 week ago" do
|
150
150
|
it { expect(user.should_remind?).to be true }
|
151
|
-
it { expect(reminder.body.encoded).to include(
|
151
|
+
it { expect(reminder.body.encoded).to include('you've never submitted solutions') }
|
152
152
|
end
|
153
153
|
|
154
154
|
context "last submission 2 weeks ago" do
|
155
155
|
let(:days_since_user_creation) { 16 }
|
156
156
|
|
157
157
|
it { expect(user.should_remind?).to be true }
|
158
|
-
it { expect(reminder.body.encoded).to include(
|
158
|
+
it { expect(reminder.body.encoded).to include('you've never submitted solutions') }
|
159
159
|
end
|
160
160
|
|
161
161
|
context "last submission 3 weeks ago" do
|
162
162
|
let(:days_since_user_creation) { 26 }
|
163
163
|
|
164
164
|
it { expect(user.should_remind?).to be true }
|
165
|
-
it { expect(reminder.body.encoded).to include(
|
165
|
+
it { expect(reminder.body.encoded).to include('you've never submitted solutions') }
|
166
166
|
end
|
167
167
|
|
168
168
|
context "last submission 4 weeks ago" do
|
@@ -178,4 +178,19 @@ RSpec.describe UserMailer, type: :mailer do
|
|
178
178
|
it { expect(user.should_remind?).to be false }
|
179
179
|
end
|
180
180
|
end
|
181
|
+
|
182
|
+
describe 'welcome email' do
|
183
|
+
let(:email) { UserMailer.welcome_email(user, organization) }
|
184
|
+
|
185
|
+
let(:non_custom_welcome_orga) { create :organization }
|
186
|
+
let(:custom_welcome_orga) { create :organization, welcome_email_template: 'hello <%= @user.first_name %>!' }
|
187
|
+
|
188
|
+
let(:user) { create :user, first_name: 'some name' }
|
189
|
+
|
190
|
+
context 'when organization does have a custom welcome template' do
|
191
|
+
let(:organization) { custom_welcome_orga }
|
192
|
+
|
193
|
+
it { expect(email.body.encoded).to eq 'hello some name!' }
|
194
|
+
end
|
195
|
+
end
|
181
196
|
end
|
data/spec/teaspoon_env.rb
CHANGED
@@ -3,6 +3,8 @@ unless defined?(Rails)
|
|
3
3
|
require File.expand_path("../dummy/config/environment", __FILE__)
|
4
4
|
end
|
5
5
|
|
6
|
+
# Enable this line for more verbose debugging
|
7
|
+
# Selenium::WebDriver.logger.level = :debug
|
6
8
|
|
7
9
|
Teaspoon.configure do |config|
|
8
10
|
# Determines where the Teaspoon routes will be mounted. Changing this to "/jasmine" would allow you to browse to
|
@@ -106,8 +108,12 @@ Teaspoon.configure do |config|
|
|
106
108
|
# Capybara Webkit: https://github.com/modeset/teaspoon/wiki/Using-Capybara-Webkit
|
107
109
|
# config.driver = :capybara_webkit
|
108
110
|
config.driver = :selenium
|
109
|
-
config.driver_options = {
|
110
|
-
|
111
|
+
config.driver_options = {
|
112
|
+
client_driver: :firefox,
|
113
|
+
selenium_options: {
|
114
|
+
options: Selenium::WebDriver::Firefox::Options.new(log_level: :warn)
|
115
|
+
}
|
116
|
+
}
|
111
117
|
|
112
118
|
# Specify the timeout for the driver. Specs are expected to complete within this time frame or the run will be
|
113
119
|
# considered a failure. This is to avoid issues that can arise where tests stall.
|
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
(function() {
|
4
4
|
var locale = document.querySelector("html").lang || 'es';
|
5
|
-
var languageCode = locale.split("-")[0];
|
6
5
|
|
7
6
|
var keywords = [
|
8
7
|
"program", "procedure", "function", "interactive", "if",
|
@@ -23,8 +22,8 @@
|
|
23
22
|
en: ["Put", "Grab", "Move", "GoToEdge", "EmptyBoardContents", "numStones", "anyStones", "canMove", "next", "prev", "opposite", "minBool", "maxBool", "minDir", "maxDir", "minColor", "maxColor"]
|
24
23
|
};
|
25
24
|
|
26
|
-
const localizedKeywordsAndBuiltins = keywords.concat(builtins[
|
27
|
-
const localizedAtoms = atoms[
|
25
|
+
const localizedKeywordsAndBuiltins = keywords.concat(builtins[locale]);
|
26
|
+
const localizedAtoms = atoms[locale];
|
28
27
|
|
29
28
|
var buildList = function(values) {
|
30
29
|
return values.join('|');
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mumuki-laboratory
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 7.
|
4
|
+
version: 7.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Franco Bulgarelli
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 7.
|
33
|
+
version: 7.8.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 7.
|
40
|
+
version: 7.8.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: mumukit-bridge
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -344,7 +344,9 @@ files:
|
|
344
344
|
- app/assets/javascripts/mumuki_laboratory/application/csrf-token.js
|
345
345
|
- app/assets/javascripts/mumuki_laboratory/application/custom-editor.js
|
346
346
|
- app/assets/javascripts/mumuki_laboratory/application/discussions.js
|
347
|
+
- app/assets/javascripts/mumuki_laboratory/application/editors.js
|
347
348
|
- app/assets/javascripts/mumuki_laboratory/application/elipsis.js
|
349
|
+
- app/assets/javascripts/mumuki_laboratory/application/exercise.js
|
348
350
|
- app/assets/javascripts/mumuki_laboratory/application/free-form.js
|
349
351
|
- app/assets/javascripts/mumuki_laboratory/application/inputs.js
|
350
352
|
- app/assets/javascripts/mumuki_laboratory/application/interval.js
|
@@ -361,6 +363,8 @@ files:
|
|
361
363
|
- app/assets/javascripts/mumuki_laboratory/application/results-renderer.js
|
362
364
|
- app/assets/javascripts/mumuki_laboratory/application/speech-bubble-renderer.js
|
363
365
|
- app/assets/javascripts/mumuki_laboratory/application/submission.js
|
366
|
+
- app/assets/javascripts/mumuki_laboratory/application/submissions-store.js
|
367
|
+
- app/assets/javascripts/mumuki_laboratory/application/sync-mode.js
|
364
368
|
- app/assets/javascripts/mumuki_laboratory/application/timer.js
|
365
369
|
- app/assets/javascripts/mumuki_laboratory/application/tooltip.js
|
366
370
|
- app/assets/javascripts/mumuki_laboratory/application/upload.js
|
@@ -461,9 +465,9 @@ files:
|
|
461
465
|
- app/helpers/editor_tabs_helper.rb
|
462
466
|
- app/helpers/email_helper.rb
|
463
467
|
- app/helpers/exercise_input_helper.rb
|
468
|
+
- app/helpers/globals_helper.rb
|
464
469
|
- app/helpers/icons_helper.rb
|
465
470
|
- app/helpers/links_helper.rb
|
466
|
-
- app/helpers/locale_helper.rb
|
467
471
|
- app/helpers/menu_bar_helper.rb
|
468
472
|
- app/helpers/messages_helper.rb
|
469
473
|
- app/helpers/multiple_file_editor_helper.rb
|
@@ -475,7 +479,6 @@ files:
|
|
475
479
|
- app/helpers/progress_bar_helper.rb
|
476
480
|
- app/helpers/progress_helper.rb
|
477
481
|
- app/helpers/runner_assets_helper.rb
|
478
|
-
- app/helpers/version_helper.rb
|
479
482
|
- app/mailers/application_mailer.rb
|
480
483
|
- app/mailers/user_mailer.rb
|
481
484
|
- app/views/appendixes/show.html.erb
|
@@ -595,6 +598,7 @@ files:
|
|
595
598
|
- lib/mumuki/laboratory/controllers/dynamic_errors.rb
|
596
599
|
- lib/mumuki/laboratory/controllers/embedded_mode.rb
|
597
600
|
- lib/mumuki/laboratory/controllers/exercise_seed.rb
|
601
|
+
- lib/mumuki/laboratory/controllers/incognito_mode.rb
|
598
602
|
- lib/mumuki/laboratory/controllers/nested_in_exercise.rb
|
599
603
|
- lib/mumuki/laboratory/controllers/notifications.rb
|
600
604
|
- lib/mumuki/laboratory/controllers/results_rendering.rb
|
@@ -719,10 +723,15 @@ files:
|
|
719
723
|
- spec/helpers/with_navigation_spec.rb
|
720
724
|
- spec/javascripts/bridge-spec.js
|
721
725
|
- spec/javascripts/csrf-token-spec.js
|
726
|
+
- spec/javascripts/editors-spec.js
|
722
727
|
- spec/javascripts/elipsis-spec.js
|
728
|
+
- spec/javascripts/exercise-spec.js
|
729
|
+
- spec/javascripts/global-spec.js
|
723
730
|
- spec/javascripts/results-renderers-spec.js
|
724
731
|
- spec/javascripts/spec-helper.js
|
725
732
|
- spec/javascripts/speech-bubble-renderer-spec.js
|
733
|
+
- spec/javascripts/submissions-store-spec.js
|
734
|
+
- spec/javascripts/sync-mode-spec.js
|
726
735
|
- spec/javascripts/timeout-spec.js
|
727
736
|
- spec/javascripts/timer-spec.js
|
728
737
|
- spec/login_helper.rb
|
@@ -876,13 +885,18 @@ test_files:
|
|
876
885
|
- spec/capybara_helper.rb
|
877
886
|
- spec/evaluation_helper.rb
|
878
887
|
- spec/javascripts/bridge-spec.js
|
888
|
+
- spec/javascripts/exercise-spec.js
|
889
|
+
- spec/javascripts/global-spec.js
|
879
890
|
- spec/javascripts/speech-bubble-renderer-spec.js
|
880
891
|
- spec/javascripts/timeout-spec.js
|
881
892
|
- spec/javascripts/results-renderers-spec.js
|
882
893
|
- spec/javascripts/csrf-token-spec.js
|
883
894
|
- spec/javascripts/elipsis-spec.js
|
884
895
|
- spec/javascripts/timer-spec.js
|
896
|
+
- spec/javascripts/editors-spec.js
|
885
897
|
- spec/javascripts/spec-helper.js
|
898
|
+
- spec/javascripts/submissions-store-spec.js
|
899
|
+
- spec/javascripts/sync-mode-spec.js
|
886
900
|
- spec/controllers/discussions_controller_spec.rb
|
887
901
|
- spec/controllers/chapters_controller_spec.rb
|
888
902
|
- spec/controllers/students_api_controller_spec.rb
|