2017-04-20 04:46:28 +08:00
# encoding: utf-8
2019-04-30 08:27:42 +08:00
# frozen_string_literal: true
2017-04-20 04:46:28 +08:00
2022-07-28 10:27:38 +08:00
RSpec . describe ThemeField do
2021-12-23 01:09:43 +08:00
fab! ( :theme ) { Fabricate ( :theme ) }
2022-10-19 01:20:10 +08:00
before { ThemeJavascriptCompiler . disable_terser! }
after { ThemeJavascriptCompiler . enable_terser! }
2018-03-05 08:04:23 +08:00
2018-08-08 12:46:34 +08:00
describe " scope: find_by_theme_ids " do
it " returns result in the specified order " do
theme2 = Fabricate ( :theme )
theme3 = Fabricate ( :theme )
( 0 .. 1 ) . each do | num |
ThemeField . create! ( theme : theme , target_id : num , name : " header " , value : " <a>html</a> " )
ThemeField . create! ( theme : theme2 , target_id : num , name : " header " , value : " <a>html</a> " )
ThemeField . create! ( theme : theme3 , target_id : num , name : " header " , value : " <a>html</a> " )
end
expect ( ThemeField . find_by_theme_ids (
[ theme3 . id , theme . id , theme2 . id ]
) . pluck ( :theme_id ) ) . to eq (
[ theme3 . id , theme3 . id , theme . id , theme . id , theme2 . id , theme2 . id ]
)
end
end
2018-10-15 12:55:23 +08:00
it 'does not insert a script tag when there are no inline script' do
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " body_tag " , value : '<div>new div</div>' )
2019-04-12 18:36:08 +08:00
theme_field . ensure_baked!
2018-10-15 12:55:23 +08:00
expect ( theme_field . value_baked ) . to_not include ( '<script' )
end
2019-11-12 22:30:19 +08:00
it 'adds an error when optimized image links are included' do
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " body_tag " , value : << ~ HTML )
< img src = " http://mysite.invalid/uploads/default/optimized/1X/6d749a141f513f88f167e750e528515002043da1_2_1282x1000.png " / >
HTML
theme_field . ensure_baked!
expect ( theme_field . error ) . to include ( I18n . t ( " themes.errors.optimized_link " ) )
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " scss " , value : << ~ SCSS )
body {
background : url ( http : / /m ysite . invalid / uploads / default / optimized / 1 X / 6 d749a141f513f88f167e750e528515002043da1_2_1282x1000 . png ) ;
}
SCSS
theme_field . ensure_baked!
expect ( theme_field . error ) . to include ( I18n . t ( " themes.errors.optimized_link " ) )
theme_field . update ( value : << ~ SCSS )
body {
background : url ( http : / /no tdiscourse . invalid / optimized / my_image . png ) ;
}
SCSS
theme_field . ensure_baked!
expect ( theme_field . error ) . to eq ( nil )
end
2018-10-15 12:55:23 +08:00
it 'only extracts inline javascript to an external file' do
2018-10-18 14:17:10 +08:00
html = << ~ HTML
2020-05-07 04:57:14 +08:00
< script type = " text/discourse-plugin " version = " 0.8 " >
var a = " inline discourse plugin " ;
< / script>
< script type = " text/template " data - template = " custom-template " >
< div > custom script type < / div>
< / script>
< script >
var b = " inline raw script " ;
< / script>
< script type = " texT/jAvasCripT " >
var c = " text/javascript " ;
< / script>
< script type = " application/javascript " >
var d = " application/javascript " ;
< / script>
< script src = " /external-script.js " > < / script>
2018-10-18 14:17:10 +08:00
HTML
2018-10-15 12:55:23 +08:00
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " header " , value : html )
2019-04-12 18:36:08 +08:00
theme_field . ensure_baked!
2022-06-20 09:47:37 +08:00
expect ( theme_field . value_baked ) . to include ( " <script defer= \" \" src= \" #{ theme_field . javascript_cache . url } \" data-theme-id= \" 1 \" ></script> " )
2018-10-15 12:55:23 +08:00
expect ( theme_field . value_baked ) . to include ( " external-script.js " )
2018-11-02 04:01:46 +08:00
expect ( theme_field . value_baked ) . to include ( '<script type="text/template"' )
expect ( theme_field . javascript_cache . content ) . to include ( 'a = "inline discourse plugin"' )
expect ( theme_field . javascript_cache . content ) . to include ( 'b = "inline raw script"' )
expect ( theme_field . javascript_cache . content ) . to include ( 'c = "text/javascript"' )
expect ( theme_field . javascript_cache . content ) . to include ( 'd = "application/javascript"' )
end
it 'adds newlines between the extracted javascripts' do
html = << ~ HTML
2020-05-07 04:57:14 +08:00
< script > var a = 10 < / script>
< script > var b = 10 < / script>
2018-11-02 04:01:46 +08:00
HTML
DEV: Correctly tag heredocs (#16061)
This allows text editors to use correct syntax coloring for the heredoc sections.
Heredoc tag names we use:
languages: SQL, JS, RUBY, LUA, HTML, CSS, SCSS, SH, HBS, XML, YAML/YML, MF, ICS
other: MD, TEXT/TXT, RAW, EMAIL
2022-03-01 03:50:55 +08:00
extracted = << ~ JS
2020-05-07 04:57:14 +08:00
var a = 10
var b = 10
DEV: Correctly tag heredocs (#16061)
This allows text editors to use correct syntax coloring for the heredoc sections.
Heredoc tag names we use:
languages: SQL, JS, RUBY, LUA, HTML, CSS, SCSS, SH, HBS, XML, YAML/YML, MF, ICS
other: MD, TEXT/TXT, RAW, EMAIL
2022-03-01 03:50:55 +08:00
JS
2018-11-02 04:01:46 +08:00
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " header " , value : html )
2019-04-12 18:36:08 +08:00
theme_field . ensure_baked!
2019-01-17 19:46:11 +08:00
expect ( theme_field . javascript_cache . content ) . to include ( extracted )
2018-10-15 12:55:23 +08:00
end
it " correctly extracts and generates errors for transpiled js " do
2017-04-20 04:46:28 +08:00
html = <<HTML
< script type = " text/discourse-plugin " version = " 0.8 " >
badJavaScript ( ;
< / script>
HTML
2017-08-31 12:06:56 +08:00
2017-05-03 04:01:01 +08:00
field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " header " , value : html )
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2017-04-20 04:46:28 +08:00
expect ( field . error ) . not_to eq ( nil )
2022-06-20 09:47:37 +08:00
expect ( field . value_baked ) . to include ( " <script defer= \" \" src= \" #{ field . javascript_cache . url } \" data-theme-id= \" 1 \" ></script> " )
2022-10-17 22:04:04 +08:00
expect ( field . javascript_cache . content ) . to include ( " [THEME 1 'Default'] Compile error " )
2017-08-31 12:06:56 +08:00
field . update! ( value : '' )
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2017-04-20 04:46:28 +08:00
expect ( field . error ) . to eq ( nil )
end
2018-04-03 17:53:00 +08:00
it " allows us to use theme settings in handlebars templates " do
html = <<HTML
< script type = 'text/x-handlebars' data - template - name = 'my-template' >
< div class = " testing-div " > { { themeSettings . string_setting } } < / div>
< / script>
HTML
2019-04-12 18:36:08 +08:00
ThemeField . create! ( theme_id : 1 , target_id : 3 , name : " yaml " , value : " string_setting: \" test text \\ \" 123! \" " ) . ensure_baked!
2018-10-15 12:55:23 +08:00
theme_field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " head_tag " , value : html )
2019-04-12 18:36:08 +08:00
theme_field . ensure_baked!
2018-10-15 12:55:23 +08:00
javascript_cache = theme_field . javascript_cache
2018-04-03 17:53:00 +08:00
2022-06-20 09:47:37 +08:00
expect ( theme_field . value_baked ) . to include ( " <script defer= \" \" src= \" #{ javascript_cache . url } \" data-theme-id= \" 1 \" ></script> " )
2018-10-15 12:55:23 +08:00
expect ( javascript_cache . content ) . to include ( " testing-div " )
expect ( javascript_cache . content ) . to include ( " string_setting " )
2019-01-17 19:46:11 +08:00
expect ( javascript_cache . content ) . to include ( " test text \\ \" 123! " )
2022-09-04 19:01:10 +08:00
expect ( javascript_cache . content ) . to include ( " define( \" discourse/theme- #{ theme_field . theme_id } /discourse/templates/my-template \" " )
2018-04-03 17:53:00 +08:00
end
2017-04-20 04:46:28 +08:00
it " correctly generates errors for transpiled css " do
css = " body { "
2017-05-03 04:01:01 +08:00
field = ThemeField . create! ( theme_id : 1 , target_id : 0 , name : " scss " , value : css )
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2017-04-20 04:46:28 +08:00
expect ( field . error ) . not_to eq ( nil )
2021-02-03 02:09:41 +08:00
field . value = " @import 'missingfile'; "
2017-04-20 04:46:28 +08:00
field . save!
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2021-03-13 00:17:42 +08:00
expect ( field . error ) . to include ( " File to import not found or unreadable: missingfile " )
2017-04-21 04:55:09 +08:00
2021-02-03 02:09:41 +08:00
field . value = " body {color: blue}; "
field . save!
field . ensure_baked!
2017-04-20 04:46:28 +08:00
expect ( field . error ) . to eq ( nil )
end
2017-05-11 02:43:05 +08:00
2019-04-12 18:36:08 +08:00
it " allows importing scss files " do
2021-02-03 02:09:41 +08:00
main_field = theme . set_field ( target : :common , name : :scss , value : " .class1{color: red} \n @import 'rootfile1'; \n @import 'rootfile3'; " )
2019-04-12 18:36:08 +08:00
theme . set_field ( target : :extra_scss , name : " rootfile1 " , value : " .class2{color:green} \n @import 'foldername/subfile1'; " )
theme . set_field ( target : :extra_scss , name : " rootfile2 " , value : " .class3{color:green} " )
theme . set_field ( target : :extra_scss , name : " foldername/subfile1 " , value : " .class4{color:yellow} \n @import 'subfile2'; " )
theme . set_field ( target : :extra_scss , name : " foldername/subfile2 " , value : " .class5{color:yellow} \n @import '../rootfile2'; " )
2021-02-03 02:09:41 +08:00
theme . set_field ( target : :extra_scss , name : " rootfile3 " , value : " .class6{color:green} " )
2019-04-12 18:36:08 +08:00
theme . save!
result = main_field . compile_scss [ 0 ]
expect ( result ) . to include ( " .class1 " )
expect ( result ) . to include ( " .class2 " )
expect ( result ) . to include ( " .class3 " )
expect ( result ) . to include ( " .class4 " )
expect ( result ) . to include ( " .class5 " )
2021-02-03 02:09:41 +08:00
expect ( result ) . to include ( " .class6 " )
2019-04-12 18:36:08 +08:00
end
2019-06-03 17:41:00 +08:00
it " correctly handles extra JS fields " do
2020-04-07 00:24:59 +08:00
js_field = theme . set_field ( target : :extra_js , name : " discourse/controllers/discovery.js.es6 " , value : " import 'discourse/lib/ajax'; console.log('hello from .js.es6'); " )
2022-04-07 05:58:10 +08:00
_js_2_field = theme . set_field ( target : :extra_js , name : " discourse/controllers/discovery-2.js " , value : " import 'discourse/lib/ajax'; console.log('hello from .js'); " )
2019-06-03 17:41:00 +08:00
hbs_field = theme . set_field ( target : :extra_js , name : " discourse/templates/discovery.hbs " , value : " {{hello-world}} " )
2020-02-12 03:38:12 +08:00
raw_hbs_field = theme . set_field ( target : :extra_js , name : " discourse/templates/discovery.hbr " , value : " {{hello-world}} " )
hbr_field = theme . set_field ( target : :extra_js , name : " discourse/templates/other_discovery.hbr " , value : " {{hello-world}} " )
2019-06-03 17:41:00 +08:00
unknown_field = theme . set_field ( target : :extra_js , name : " discourse/controllers/discovery.blah " , value : " this wont work " )
theme . save!
2021-04-12 20:02:58 +08:00
js_field . reload
2022-10-17 22:04:04 +08:00
expect ( js_field . value_baked ) . to eq ( " baked " )
expect ( js_field . value_baked ) . to eq ( " baked " )
expect ( js_field . value_baked ) . to eq ( " baked " )
2019-06-03 17:41:00 +08:00
# All together
2022-09-01 18:50:46 +08:00
expect ( theme . javascript_cache . content ) . to include ( " define( \" discourse/theme- #{ theme . id } /discourse/templates/discovery \" , [ \" exports \" , \" @ember/template-factory \" ] " )
2020-05-06 00:15:03 +08:00
expect ( theme . javascript_cache . content ) . to include ( 'addRawTemplate("discovery"' )
2021-04-12 20:02:58 +08:00
expect ( theme . javascript_cache . content ) . to include ( " define( \" discourse/theme- #{ theme . id } /controllers/discovery \" " )
expect ( theme . javascript_cache . content ) . to include ( " define( \" discourse/theme- #{ theme . id } /controllers/discovery-2 \" " )
2022-08-09 18:53:24 +08:00
expect ( theme . javascript_cache . content ) . to include ( " const settings = " )
2022-10-17 22:04:04 +08:00
expect ( theme . javascript_cache . content ) . to include ( " [THEME #{ theme . id } ' #{ theme . name } '] Compile error: unknown file extension 'blah' (discourse/controllers/discovery.blah) " )
2022-10-19 01:20:10 +08:00
# Check sourcemap
expect ( theme . javascript_cache . source_map ) . to eq ( nil )
ThemeJavascriptCompiler . enable_terser!
js_field . update ( compiler_version : " 0 " )
theme . save!
expect ( theme . javascript_cache . source_map ) . not_to eq ( nil )
map = JSON . parse ( theme . javascript_cache . source_map )
expect ( map [ " sources " ] ) . to contain_exactly (
" discourse/controllers/discovery-2.js " ,
" discourse/controllers/discovery.blah " ,
" discourse/controllers/discovery.js " ,
" discourse/templates/discovery.js " ,
" discovery.js " ,
" other_discovery.js "
)
expect ( map [ " sourceRoot " ] ) . to eq ( " theme- #{ theme . id } / " )
expect ( map [ " sourcesContent " ] . length ) . to eq ( 6 )
2019-06-03 17:41:00 +08:00
end
2017-12-19 23:10:44 +08:00
def create_upload_theme_field! ( name )
ThemeField . create! (
theme_id : 1 ,
target_id : 0 ,
value : " " ,
type_id : ThemeField . types [ :theme_upload_var ] ,
name : name ,
2019-04-12 18:36:08 +08:00
) . tap { | tf | tf . ensure_baked! }
2017-12-19 23:10:44 +08:00
end
it " ensures we don't use invalid SCSS variable names " do
expect { create_upload_theme_field! ( " 42 " ) } . to raise_error ( ActiveRecord :: RecordInvalid )
expect { create_upload_theme_field! ( " a42 " ) } . not_to raise_error
end
2018-03-05 08:04:23 +08:00
def get_fixture ( type )
File . read ( " #{ Rails . root } /spec/fixtures/theme_settings/ #{ type } _settings.yaml " )
end
def create_yaml_field ( value )
field = ThemeField . create! ( theme_id : 1 , target_id : Theme . targets [ :settings ] , name : " yaml " , value : value )
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2018-03-05 08:04:23 +08:00
field
end
let ( :key ) { " themes.settings_errors " }
2019-03-08 22:49:06 +08:00
it " forces re-transpilation of theme JS when settings YAML changes " do
settings_field = ThemeField . create! ( theme : theme , target_id : Theme . targets [ :settings ] , name : " yaml " , value : " setting: 5 " )
html = << ~ HTML
< script type = " text/discourse-plugin " version = " 0.8 " >
alert ( settings . setting ) ;
< / script>
HTML
js_field = ThemeField . create! ( theme : theme , target_id : ThemeField . types [ :html ] , name : " header " , value : html )
old_value_baked = js_field . value_baked
settings_field . update! ( value : " setting: 66 " )
js_field . reload
expect ( js_field . value_baked ) . to eq ( nil )
js_field . ensure_baked!
expect ( js_field . value_baked ) . to be_present
expect ( js_field . value_baked ) . not_to eq ( old_value_baked )
end
2018-03-05 08:04:23 +08:00
it " generates errors for bad YAML " do
yaml = " invalid_setting 5 "
field = create_yaml_field ( yaml )
expect ( field . error ) . to eq ( I18n . t ( " #{ key } .invalid_yaml " ) )
field . value = " valid_setting: true "
field . save!
2019-04-12 18:36:08 +08:00
field . ensure_baked!
2018-03-05 08:04:23 +08:00
expect ( field . error ) . to eq ( nil )
end
it " generates errors when default value's type doesn't match setting type " do
field = create_yaml_field ( get_fixture ( " invalid " ) )
expect ( field . error ) . to include ( I18n . t ( " #{ key } .default_not_match_type " , name : " no_match_setting " ) )
end
it " generates errors when no default value is passed " do
field = create_yaml_field ( get_fixture ( " invalid " ) )
expect ( field . error ) . to include ( I18n . t ( " #{ key } .default_value_missing " , name : " no_default_setting " ) )
end
it " generates errors when invalid type is passed " do
field = create_yaml_field ( get_fixture ( " invalid " ) )
expect ( field . error ) . to include ( I18n . t ( " #{ key } .data_type_not_a_number " , name : " invalid_type_setting " ) )
end
it " generates errors when default value is not within allowed range " do
field = create_yaml_field ( get_fixture ( " invalid " ) )
expect ( field . error ) . to include ( I18n . t ( " #{ key } .default_out_range " , name : " default_out_of_range " ) )
expect ( field . error ) . to include ( I18n . t ( " #{ key } .default_out_range " , name : " string_default_out_of_range " ) )
end
it " works correctly when valid yaml is provided " do
field = create_yaml_field ( get_fixture ( " valid " ) )
expect ( field . error ) . to be_nil
end
2019-01-17 19:46:11 +08:00
describe " locale fields " do
let! ( :theme ) { Fabricate ( :theme ) }
let! ( :theme2 ) { Fabricate ( :theme ) }
let! ( :theme3 ) { Fabricate ( :theme ) }
let! ( :en1 ) {
2020-05-07 04:57:14 +08:00
ThemeField . create! ( theme : theme , target_id : Theme . targets [ :translations ] , name : " en " ,
value : { en : { somestring1 : " helloworld " , group : { key1 : " enval1 " } } }
2019-01-17 19:46:11 +08:00
. deep_stringify_keys . to_yaml
)
}
let! ( :fr1 ) {
ThemeField . create! ( theme : theme , target_id : Theme . targets [ :translations ] , name : " fr " ,
value : { fr : { somestring1 : " bonjourworld " , group : { key2 : " frval2 " } } }
. deep_stringify_keys . to_yaml
)
}
let! ( :fr2 ) { ThemeField . create! ( theme : theme2 , target_id : Theme . targets [ :translations ] , name : " fr " , value : " " ) }
2020-05-07 04:57:14 +08:00
let! ( :en2 ) { ThemeField . create! ( theme : theme2 , target_id : Theme . targets [ :translations ] , name : " en " , value : " " ) }
2019-01-17 19:46:11 +08:00
let! ( :ca3 ) { ThemeField . create! ( theme : theme3 , target_id : Theme . targets [ :translations ] , name : " ca " , value : " " ) }
2020-05-07 04:57:14 +08:00
let! ( :en3 ) { ThemeField . create! ( theme : theme3 , target_id : Theme . targets [ :translations ] , name : " en " , value : " " ) }
2019-01-17 19:46:11 +08:00
describe " scopes " do
2019-02-26 22:22:02 +08:00
it " filter_locale_fields returns results in the correct order " do
expect ( ThemeField . find_by_theme_ids ( [ theme3 . id , theme . id , theme2 . id ] )
. filter_locale_fields (
2020-05-07 04:57:14 +08:00
[ " en " , " fr " ]
2019-01-17 19:46:11 +08:00
) ) . to eq ( [ en3 , en1 , fr1 , en2 , fr2 ] )
end
it " find_first_locale_fields returns only the first locale for each theme " do
expect ( ThemeField . find_first_locale_fields (
2020-05-07 04:57:14 +08:00
[ theme3 . id , theme . id , theme2 . id ] , [ " ca " , " en " , " fr " ]
2019-01-17 19:46:11 +08:00
) ) . to eq ( [ ca3 , en1 , en2 ] )
end
end
describe " # raw_translation_data " do
it " errors if the top level key is incorrect " do
fr1 . update ( value : { wrongkey : { somestring1 : " bonjourworld " } } . deep_stringify_keys . to_yaml )
expect { fr1 . raw_translation_data } . to raise_error ( ThemeTranslationParser :: InvalidYaml )
end
it " errors if there are multiple top level keys " do
fr1 . update ( value : { fr : { somestring1 : " bonjourworld " } , otherkey : " hello " } . deep_stringify_keys . to_yaml )
expect { fr1 . raw_translation_data } . to raise_error ( ThemeTranslationParser :: InvalidYaml )
end
it " errors if YAML includes arrays " do
fr1 . update ( value : { fr : [ " val1 " , " val2 " ] } . deep_stringify_keys . to_yaml )
expect { fr1 . raw_translation_data } . to raise_error ( ThemeTranslationParser :: InvalidYaml )
end
it " errors if YAML has invalid syntax " do
fr1 . update ( value : " fr: 'valuewithoutclosequote " )
expect { fr1 . raw_translation_data } . to raise_error ( ThemeTranslationParser :: InvalidYaml )
end
2022-09-03 00:28:18 +08:00
it " works when locale file doesn't contain translations " do
fr1 . update ( value : " fr: " )
expect ( fr1 . translation_data ) . to eq (
fr : { } ,
en : { somestring1 : " helloworld " , group : { key1 : " enval1 " } }
)
end
2019-01-17 19:46:11 +08:00
end
describe " # translation_data " do
it " loads correctly " do
expect ( fr1 . translation_data ) . to eq (
fr : { somestring1 : " bonjourworld " , group : { key2 : " frval2 " } } ,
2020-05-07 04:57:14 +08:00
en : { somestring1 : " helloworld " , group : { key1 : " enval1 " } }
2019-01-17 19:46:11 +08:00
)
end
it " raises errors for the current locale " do
fr1 . update ( value : { wrongkey : " hello " } . deep_stringify_keys . to_yaml )
expect { fr1 . translation_data } . to raise_error ( ThemeTranslationParser :: InvalidYaml )
end
it " doesn't raise errors for the fallback locale " do
en1 . update ( value : { wrongkey : " hello " } . deep_stringify_keys . to_yaml )
expect ( fr1 . translation_data ) . to eq (
fr : { somestring1 : " bonjourworld " , group : { key2 : " frval2 " } }
)
end
it " merges any overrides " do
# Overrides in the current locale (so in tests that will be english)
theme . update_translation ( " group.key1 " , " overriddentest1 " )
theme . reload
expect ( fr1 . translation_data ) . to eq (
fr : { somestring1 : " bonjourworld " , group : { key2 : " frval2 " } } ,
2020-05-07 04:57:14 +08:00
en : { somestring1 : " helloworld " , group : { key1 : " overriddentest1 " } }
2019-01-17 19:46:11 +08:00
)
end
end
describe " javascript cache " do
it " is generated correctly " do
fr1 . ensure_baked!
2022-06-20 09:47:37 +08:00
expect ( fr1 . value_baked ) . to include ( " <script defer src=' #{ fr1 . javascript_cache . url } ' data-theme-id=' #{ fr1 . theme_id } '></script> " )
2019-01-17 19:46:11 +08:00
expect ( fr1 . javascript_cache . content ) . to include ( " bonjourworld " )
expect ( fr1 . javascript_cache . content ) . to include ( " helloworld " )
expect ( fr1 . javascript_cache . content ) . to include ( " enval1 " )
end
end
describe " prefix injection " do
it " injects into JS " do
html = << ~ HTML
2020-05-07 04:57:14 +08:00
< script type = " text/discourse-plugin " version = " 0.8 " >
var a = " inline discourse plugin " ;
< / script>
2019-01-17 19:46:11 +08:00
HTML
theme_field = ThemeField . create! ( theme_id : theme . id , target_id : 0 , name : " head_tag " , value : html )
2019-04-12 18:36:08 +08:00
theme_field . ensure_baked!
2019-01-17 19:46:11 +08:00
javascript_cache = theme_field . javascript_cache
expect ( javascript_cache . content ) . to include ( " inline discourse plugin " )
expect ( javascript_cache . content ) . to include ( " theme_translations. #{ theme . id } . " )
end
end
end
2022-07-28 00:14:14 +08:00
describe " SVG sprite theme fields " do
2020-11-25 07:49:12 +08:00
let ( :upload ) { Fabricate ( :upload ) }
let ( :theme ) { Fabricate ( :theme ) }
let ( :theme_field ) { ThemeField . create! ( theme : theme , target_id : 0 , name : SvgSprite . theme_sprite_variable_name , upload : upload , value : " " , value_baked : " baked " , type_id : ThemeField . types [ :theme_upload_var ] ) }
it " is rebaked when upload changes " do
theme_field . update ( upload : Fabricate ( :upload ) )
expect ( theme_field . value_baked ) . to eq ( nil )
end
2021-07-15 03:18:29 +08:00
it " clears SVG sprite cache when upload is deleted " do
fname = " custom-theme-icon-sprite.svg "
sprite = UploadCreator . new ( file_from_fixtures ( fname ) , fname , for_theme : true ) . create_for ( - 1 )
theme_field . update ( upload : sprite )
expect ( SvgSprite . custom_svg_sprites ( theme . id ) . size ) . to eq ( 1 )
theme_field . destroy!
expect ( SvgSprite . custom_svg_sprites ( theme . id ) . size ) . to eq ( 0 )
end
2021-07-26 10:35:27 +08:00
it 'crashes gracefully when svg is invalid' do
FileStore :: LocalStore . any_instance . stubs ( :path_for ) . returns ( nil )
expect ( theme_field . validate_svg_sprite_xml ) . to match ( " Error with icons-sprite " )
end
2020-11-25 07:49:12 +08:00
end
2022-07-28 00:14:14 +08:00
describe 'local js assets' do
2022-04-07 05:58:10 +08:00
let :js_content do
" // not transpiled; console.log('hello world'); "
end
let :upload_file do
tmp = Tempfile . new ( [ " jsfile " , " .js " ] )
File . write ( tmp . path , js_content )
tmp
end
after do
upload_file . unlink
end
it " correctly handles local JS asset caching " do
upload = UploadCreator . new ( upload_file , " test.js " , for_theme : true )
. create_for ( Discourse :: SYSTEM_USER_ID )
js_field = theme . set_field (
target : :common ,
type_id : ThemeField . types [ :theme_upload_var ] ,
name : 'test_js' ,
upload_id : upload . id
)
common_field = theme . set_field (
target : :common ,
name : " head_tag " ,
value : " <script>let c = 'd';</script> " ,
type : :html
)
theme . set_field (
target : :settings ,
type : :yaml ,
name : " yaml " ,
value : " hello: world "
)
theme . set_field (
target : :extra_js ,
name : " discourse/controllers/discovery.js.es6 " ,
value : " import 'discourse/lib/ajax'; console.log('hello from .js.es6'); "
)
theme . save!
# a bit fragile, but at least we test it properly
[ theme . reload . javascript_cache . content , common_field . reload . javascript_cache . content ] . each do | js |
js_to_eval = << ~ JS
var settings ;
var window = { } ;
var require = function ( name ) {
if ( name == " discourse/lib/theme-settings-store " ) {
return ( {
registerSettings : function ( id , s ) {
settings = s ;
}
} ) ;
}
}
window . require = require ;
#{js}
settings
JS
ctx = MiniRacer :: Context . new
val = ctx . eval ( js_to_eval )
ctx . dispose
expect ( val [ " theme_uploads " ] [ " test_js " ] ) . to eq ( js_field . upload . url )
expect ( val [ " theme_uploads_local " ] [ " test_js " ] ) . to eq ( js_field . javascript_cache . local_url )
2022-07-29 05:20:52 +08:00
expect ( val [ " theme_uploads_local " ] [ " test_js " ] ) . to start_with ( " /theme-javascripts/ " )
2022-04-07 05:58:10 +08:00
end
# this is important, we do not want local_js_urls to leak into scss
expect ( theme . scss_variables ) . to include ( " $hello: unquote( \" world \" ); " )
expect ( theme . scss_variables ) . to include ( " $test_js: unquote( \" #{ upload . url } \" ); " )
expect ( theme . scss_variables ) . not_to include ( " theme_uploads " )
end
end
2017-04-20 04:46:28 +08:00
end