2024-07-25 12:39:01 +00:00
#!/usr/bin/env python3
2022-03-13 10:37:51 +00:00
# coding=utf-8
2021-07-11 12:07:39 +00:00
import time
2022-10-09 14:12:45 +00:00
from flask import url_for , escape
2023-05-29 14:11:43 +00:00
from . util import live_server_setup , wait_for_all_checks
2021-07-25 05:22:29 +00:00
import pytest
2022-10-12 07:53:16 +00:00
jq_support = True
2021-07-11 12:07:39 +00:00
2022-10-12 07:53:16 +00:00
try :
import jq
except ModuleNotFoundError :
jq_support = False
2021-10-21 21:25:38 +00:00
def test_setup ( live_server ) :
live_server_setup ( live_server )
2021-07-25 05:02:19 +00:00
def test_unittest_inline_html_extract ( ) :
# So lets pretend that the JSON we want is inside some HTML
content = """
< html >
food and stuff and more
< script >
alert ( ' nothing really good here ' ) ;
< / script >
< script type = " application/ld+json " >
xx { " @context " : " http://schema.org " , " @type " : " Product " , " name " : " Nan Optipro Stage 1 Baby Formula 800g " , " description " : " During the first year of life, nutrition is critical for your baby. NAN OPTIPRO 1 is tailored to ensure your formula fed infant receives balanced, high quality nutrition.<br />Starter infant formula. The age optimised protein source (whey dominant) is from cow’ s milk.<br />Backed by more than 150 years of Nestlé expertise.<br />For hygiene and convenience, it is available in an innovative packaging format with a separate storage area for the scoop, and a semi-transparent window which allows you to see how much powder is left in the can without having to open it. " , " image " : " https://cdn0.woolworths.media/content/wowproductimages/large/155536.jpg " , " brand " : { " @context " : " http://schema.org " , " @type " : " Organization " , " name " : " Nan " } , " gtin13 " : " 7613287517388 " , " offers " : { " @context " : " http://schema.org " , " @type " : " Offer " , " potentialAction " : { " @context " : " http://schema.org " , " @type " : " BuyAction " } , " availability " : " http://schema.org/InStock " , " itemCondition " : " http://schema.org/NewCondition " , " price " : 23.5 , " priceCurrency " : " AUD " } , " review " : [ ] , " sku " : " 155536 " }
< / script >
< body >
and it can also be repeated
< script type = " application/ld+json " >
{ " @context " : " http://schema.org " , " @type " : " Product " , " name " : " Nan Optipro Stage 1 Baby Formula 800g " , " description " : " During the first year of life, nutrition is critical for your baby. NAN OPTIPRO 1 is tailored to ensure your formula fed infant receives balanced, high quality nutrition.<br />Starter infant formula. The age optimised protein source (whey dominant) is from cow’ s milk.<br />Backed by more than 150 years of Nestlé expertise.<br />For hygiene and convenience, it is available in an innovative packaging format with a separate storage area for the scoop, and a semi-transparent window which allows you to see how much powder is left in the can without having to open it. " , " image " : " https://cdn0.woolworths.media/content/wowproductimages/large/155536.jpg " , " brand " : { " @context " : " http://schema.org " , " @type " : " Organization " , " name " : " Nan " } , " gtin13 " : " 7613287517388 " , " offers " : { " @context " : " http://schema.org " , " @type " : " Offer " , " potentialAction " : { " @context " : " http://schema.org " , " @type " : " BuyAction " } , " availability " : " http://schema.org/InStock " , " itemCondition " : " http://schema.org/NewCondition " , " price " : 23.5 , " priceCurrency " : " AUD " } , " review " : [ ] , " sku " : " 155536 " }
< / script >
< h4 > ok < / h4 >
< / body >
< / html >
"""
from . . import html_tools
# See that we can find the second <script> one, which is not broken, and matches our filter
2024-06-21 11:31:03 +00:00
text = html_tools . extract_json_as_string ( content , " json:$.offers.priceCurrency " )
assert text == ' " AUD " '
text = html_tools . extract_json_as_string ( ' { " id " :5} ' , " json:$.id " )
assert text == " 5 "
2021-07-25 05:02:19 +00:00
2022-10-09 14:12:45 +00:00
# also check for jq
2022-10-12 07:53:16 +00:00
if jq_support :
2024-06-21 11:31:03 +00:00
text = html_tools . extract_json_as_string ( content , " jq:.offers.priceCurrency " )
assert text == ' " AUD " '
2022-10-09 14:12:45 +00:00
2022-10-12 07:53:16 +00:00
text = html_tools . extract_json_as_string ( ' { " id " :5} ' , " jq:.id " )
assert text == " 5 "
2022-10-09 14:12:45 +00:00
2024-06-21 11:31:03 +00:00
text = html_tools . extract_json_as_string ( content , " jqraw:.offers.priceCurrency " )
assert text == " AUD "
text = html_tools . extract_json_as_string ( ' { " id " :5} ' , " jqraw:.id " )
assert text == " 5 "
2021-07-25 05:02:19 +00:00
2021-07-25 05:22:29 +00:00
# When nothing at all is found, it should throw JSONNOTFound
# Which is caught and shown to the user in the watch-overview table
with pytest . raises ( html_tools . JSONNotFound ) as e_info :
2022-10-09 14:12:45 +00:00
html_tools . extract_json_as_string ( ' COMPLETE GIBBERISH, NO JSON! ' , " json:$.id " )
2022-10-12 07:53:16 +00:00
if jq_support :
with pytest . raises ( html_tools . JSONNotFound ) as e_info :
html_tools . extract_json_as_string ( ' COMPLETE GIBBERISH, NO JSON! ' , " jq:.id " )
2021-07-25 05:02:19 +00:00
2024-06-21 11:31:03 +00:00
with pytest . raises ( html_tools . JSONNotFound ) as e_info :
html_tools . extract_json_as_string ( ' COMPLETE GIBBERISH, NO JSON! ' , " jqraw:.id " )
2023-05-30 06:57:17 +00:00
def test_unittest_inline_extract_body ( ) :
content = """
< html >
< head > < / head >
< body >
< pre style = " word-wrap: break-word; white-space: pre-wrap; " >
{ " testKey " : 42 }
< / pre >
< / body >
< / html >
"""
from . . import html_tools
# See that we can find the second <script> one, which is not broken, and matches our filter
text = html_tools . extract_json_as_string ( content , " json:$.testKey " )
assert text == ' 42 '
2021-10-27 07:24:08 +00:00
def set_original_ext_response ( ) :
data = """
[
{
" isPriceLowered " : false ,
" status " : " ForSale " ,
" statusOrig " : " for sale "
} ,
{
" _id " : " 5e7b3e1fb3262d306323ff1e " ,
" listingsType " : " consumer " ,
" status " : " ForSale " ,
" statusOrig " : " for sale "
}
]
"""
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( data )
2022-10-09 14:12:45 +00:00
return None
2021-10-27 07:24:08 +00:00
def set_modified_ext_response ( ) :
data = """
[
{
" isPriceLowered " : false ,
" status " : " Sold " ,
" statusOrig " : " sold "
} ,
{
" _id " : " 5e7b3e1fb3262d306323ff1e " ,
" listingsType " : " consumer " ,
" isPriceLowered " : false ,
" status " : " Sold "
}
]
"""
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( data )
2022-10-09 14:12:45 +00:00
return None
2021-07-25 05:02:19 +00:00
2021-07-11 12:07:39 +00:00
def set_original_response ( ) :
test_return_data = """
{
" employees " : [
{
" id " : 1 ,
" name " : " Pankaj " ,
" salary " : " 10000 "
} ,
{
" name " : " David " ,
" salary " : " 5000 " ,
" id " : 2
}
] ,
" boss " : {
" name " : " Fat guy "
2021-10-21 21:25:38 +00:00
} ,
" available " : true
2021-07-11 12:07:39 +00:00
}
"""
2021-08-12 10:05:59 +00:00
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
2021-07-11 12:07:39 +00:00
f . write ( test_return_data )
return None
2022-01-02 21:35:33 +00:00
2022-11-03 11:13:54 +00:00
def set_json_response_with_html ( ) :
2022-01-02 21:35:33 +00:00
test_return_data = """
{
" test " : [
{
" html " : " <b> "
}
]
}
"""
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( test_return_data )
return None
2021-07-11 12:07:39 +00:00
def set_modified_response ( ) :
test_return_data = """
{
" employees " : [
{
" id " : 1 ,
" name " : " Pankaj " ,
" salary " : " 10000 "
} ,
{
" name " : " David " ,
" salary " : " 5000 " ,
" id " : 2
}
] ,
" boss " : {
2022-03-13 10:37:51 +00:00
" name " : " Örnsköldsvik "
2021-10-21 21:25:38 +00:00
} ,
" available " : false
2021-07-11 12:07:39 +00:00
}
"""
2021-08-12 10:05:59 +00:00
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
2021-07-11 12:07:39 +00:00
f . write ( test_return_data )
return None
2024-07-11 13:03:42 +00:00
def test_check_json_without_filter ( client , live_server , measure_memory_usage ) :
2022-01-02 21:35:33 +00:00
# Request a JSON document from a application/json source containing HTML
# and be sure it doesn't get chewed up by instriptis
2022-11-03 11:13:54 +00:00
set_json_response_with_html ( )
2022-01-02 21:35:33 +00:00
# Give the endpoint time to spin up
time . sleep ( 1 )
# Add our URL to the import page
2022-03-01 16:50:15 +00:00
test_url = url_for ( ' test_endpoint ' , content_type = " application/json " , _external = True )
2022-01-02 21:35:33 +00:00
client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2022-01-02 21:35:33 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2022-01-02 21:35:33 +00:00
res = client . get (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_views.preview_page " , uuid = " first " ) ,
2022-01-02 21:35:33 +00:00
follow_redirects = True
)
2022-11-03 11:13:54 +00:00
# Should still see '"html": "<b>"'
2023-03-19 20:12:22 +00:00
assert b ' "html": "<b>" ' in res . data
assert res . data . count ( b ' { ' ) > = 2
2022-01-02 21:35:33 +00:00
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2022-10-09 14:12:45 +00:00
assert b ' Deleted ' in res . data
2022-01-02 21:35:33 +00:00
2022-10-09 14:12:45 +00:00
def check_json_filter ( json_filter , client , live_server ) :
2021-07-11 12:07:39 +00:00
set_original_response ( )
# Give the endpoint time to spin up
time . sleep ( 1 )
# Add our URL to the import page
2022-03-01 16:50:15 +00:00
test_url = url_for ( ' test_endpoint ' , content_type = " application/json " , _external = True )
2021-07-11 12:07:39 +00:00
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2021-07-11 12:07:39 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
assert b " 1 Imported " in res . data
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-07-11 12:07:39 +00:00
# Goto the edit page, add our ignore text
# Add our URL to the import page
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_edit.edit_page " , uuid = " first " ) ,
2022-11-03 11:13:54 +00:00
data = { " include_filters " : json_filter ,
2021-08-12 10:05:59 +00:00
" url " : test_url ,
2023-06-19 21:29:13 +00:00
" tags " : " " ,
2021-08-12 10:05:59 +00:00
" headers " : " " ,
" fetch_backend " : " html_requests "
} ,
2021-07-11 12:07:39 +00:00
follow_redirects = True
)
assert b " Updated watch. " in res . data
# Check it saved
res = client . get (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_edit.edit_page " , uuid = " first " ) ,
2021-07-11 12:07:39 +00:00
)
2022-10-09 14:12:45 +00:00
assert bytes ( escape ( json_filter ) . encode ( ' utf-8 ' ) ) in res . data
2021-07-11 12:07:39 +00:00
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-07-11 12:07:39 +00:00
# Make a change
set_modified_response ( )
# Trigger a check
2025-03-18 09:40:22 +00:00
client . get ( url_for ( " ui.form_watch_checknow " ) , follow_redirects = True )
2021-07-11 12:07:39 +00:00
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-07-11 12:07:39 +00:00
# It should have 'unviewed' still
2025-03-25 21:57:15 +00:00
res = client . get ( url_for ( " watchlist.index " ) )
2021-07-11 12:07:39 +00:00
assert b ' unviewed ' in res . data
# Should not see this, because its not in the JSONPath we entered
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.ui_views.diff_history_page " , uuid = " first " ) )
2022-03-13 10:37:51 +00:00
2021-07-11 12:07:39 +00:00
# But the change should be there, tho its hard to test the change was detected because it will show old and new versions
2022-03-13 10:37:51 +00:00
# And #462 - check we see the proper utf-8 string there
assert " Örnsköldsvik " . encode ( ' utf-8 ' ) in res . data
2021-10-21 21:25:38 +00:00
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2022-10-09 14:12:45 +00:00
assert b ' Deleted ' in res . data
2024-07-11 13:03:42 +00:00
def test_check_jsonpath_filter ( client , live_server , measure_memory_usage ) :
2022-10-09 14:12:45 +00:00
check_json_filter ( ' json:boss.name ' , client , live_server )
2021-10-21 21:25:38 +00:00
2024-07-11 13:03:42 +00:00
def test_check_jq_filter ( client , live_server , measure_memory_usage ) :
2022-10-12 07:53:16 +00:00
if jq_support :
check_json_filter ( ' jq:.boss.name ' , client , live_server )
2021-10-21 21:25:38 +00:00
2024-07-11 13:03:42 +00:00
def test_check_jqraw_filter ( client , live_server , measure_memory_usage ) :
2024-06-21 11:31:03 +00:00
if jq_support :
check_json_filter ( ' jqraw:.boss.name ' , client , live_server )
2022-10-09 14:12:45 +00:00
def check_json_filter_bool_val ( json_filter , client , live_server ) :
2021-10-21 21:25:38 +00:00
set_original_response ( )
# Give the endpoint time to spin up
time . sleep ( 1 )
2022-03-01 16:50:15 +00:00
test_url = url_for ( ' test_endpoint ' , content_type = " application/json " , _external = True )
2021-10-21 21:25:38 +00:00
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2021-10-21 21:25:38 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
assert b " 1 Imported " in res . data
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-21 21:25:38 +00:00
# Goto the edit page, add our ignore text
# Add our URL to the import page
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_edit.edit_page " , uuid = " first " ) ,
2022-11-03 11:13:54 +00:00
data = { " include_filters " : json_filter ,
2021-10-21 21:25:38 +00:00
" url " : test_url ,
2023-06-19 21:29:13 +00:00
" tags " : " " ,
2021-10-21 21:25:38 +00:00
" headers " : " " ,
" fetch_backend " : " html_requests "
} ,
follow_redirects = True
)
assert b " Updated watch. " in res . data
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-21 21:25:38 +00:00
# Make a change
set_modified_response ( )
# Trigger a check
2025-03-18 09:40:22 +00:00
client . get ( url_for ( " ui.form_watch_checknow " ) , follow_redirects = True )
2021-10-21 21:25:38 +00:00
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-21 21:25:38 +00:00
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.ui_views.diff_history_page " , uuid = " first " ) )
2021-10-21 21:25:38 +00:00
# But the change should be there, tho its hard to test the change was detected because it will show old and new versions
assert b ' false ' in res . data
2021-10-27 07:24:08 +00:00
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2022-10-09 14:12:45 +00:00
assert b ' Deleted ' in res . data
2024-07-11 13:03:42 +00:00
def test_check_jsonpath_filter_bool_val ( client , live_server , measure_memory_usage ) :
2022-10-09 14:12:45 +00:00
check_json_filter_bool_val ( " json:$[ ' available ' ] " , client , live_server )
2024-07-11 13:03:42 +00:00
def test_check_jq_filter_bool_val ( client , live_server , measure_memory_usage ) :
2022-10-12 07:53:16 +00:00
if jq_support :
check_json_filter_bool_val ( " jq:.available " , client , live_server )
2022-10-09 14:12:45 +00:00
2024-07-11 13:03:42 +00:00
def test_check_jqraw_filter_bool_val ( client , live_server , measure_memory_usage ) :
2024-06-21 11:31:03 +00:00
if jq_support :
check_json_filter_bool_val ( " jq:.available " , client , live_server )
2021-10-27 07:24:08 +00:00
# Re #265 - Extended JSON selector test
# Stuff to consider here
# - Selector should be allowed to return empty when it doesnt match (people might wait for some condition)
# - The 'diff' tab could show the old and new content
# - Form should let us enter a selector that doesnt (yet) match anything
2022-10-09 14:12:45 +00:00
def check_json_ext_filter ( json_filter , client , live_server ) :
2021-10-27 07:24:08 +00:00
set_original_ext_response ( )
# Give the endpoint time to spin up
time . sleep ( 1 )
# Add our URL to the import page
2022-03-01 16:50:15 +00:00
test_url = url_for ( ' test_endpoint ' , content_type = " application/json " , _external = True )
2021-10-27 07:24:08 +00:00
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2021-10-27 07:24:08 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
assert b " 1 Imported " in res . data
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-27 07:24:08 +00:00
# Goto the edit page, add our ignore text
# Add our URL to the import page
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_edit.edit_page " , uuid = " first " ) ,
2022-11-03 11:13:54 +00:00
data = { " include_filters " : json_filter ,
2021-10-27 07:24:08 +00:00
" url " : test_url ,
2023-06-19 21:29:13 +00:00
" tags " : " " ,
2021-10-27 07:24:08 +00:00
" headers " : " " ,
" fetch_backend " : " html_requests "
} ,
follow_redirects = True
)
assert b " Updated watch. " in res . data
# Check it saved
res = client . get (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_edit.edit_page " , uuid = " first " ) ,
2021-10-27 07:24:08 +00:00
)
2022-10-09 14:12:45 +00:00
assert bytes ( escape ( json_filter ) . encode ( ' utf-8 ' ) ) in res . data
2021-10-27 07:24:08 +00:00
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-27 07:24:08 +00:00
# Make a change
set_modified_ext_response ( )
# Trigger a check
2025-03-18 09:40:22 +00:00
client . get ( url_for ( " ui.form_watch_checknow " ) , follow_redirects = True )
2021-10-27 07:24:08 +00:00
# Give the thread time to pick it up
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2021-10-27 07:24:08 +00:00
# It should have 'unviewed'
2025-03-25 21:57:15 +00:00
res = client . get ( url_for ( " watchlist.index " ) )
2021-10-27 07:24:08 +00:00
assert b ' unviewed ' in res . data
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.ui_views.diff_history_page " , uuid = " first " ) )
2021-10-27 07:24:08 +00:00
# We should never see 'ForSale' because we are selecting on 'Sold' in the rule,
# But we should know it triggered ('unviewed' assert above)
assert b ' ForSale ' not in res . data
assert b ' Sold ' in res . data
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2022-10-09 14:12:45 +00:00
assert b ' Deleted ' in res . data
2024-07-11 13:03:42 +00:00
def test_ignore_json_order ( client , live_server , measure_memory_usage ) :
2022-12-15 08:13:09 +00:00
# A change in order shouldn't trigger a notification
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( ' { " hello " : 123, " world " : 123} ' )
# Add our URL to the import page
test_url = url_for ( ' test_endpoint ' , content_type = " application/json " , _external = True )
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2022-12-15 08:13:09 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
assert b " 1 Imported " in res . data
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2022-12-15 08:13:09 +00:00
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( ' { " world " : 123, " hello " : 123} ' )
# Trigger a check
2025-03-18 09:40:22 +00:00
client . get ( url_for ( " ui.form_watch_checknow " ) , follow_redirects = True )
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2022-12-15 08:13:09 +00:00
2025-03-25 21:57:15 +00:00
res = client . get ( url_for ( " watchlist.index " ) )
2022-12-15 08:13:09 +00:00
assert b ' unviewed ' not in res . data
# Just to be sure it still works
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( ' { " world " : 123, " hello " : 124} ' )
# Trigger a check
2025-03-18 09:40:22 +00:00
client . get ( url_for ( " ui.form_watch_checknow " ) , follow_redirects = True )
2023-06-19 21:29:13 +00:00
wait_for_all_checks ( client )
2022-12-15 08:13:09 +00:00
2025-03-25 21:57:15 +00:00
res = client . get ( url_for ( " watchlist.index " ) )
2022-12-15 08:13:09 +00:00
assert b ' unviewed ' in res . data
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2022-12-15 08:13:09 +00:00
assert b ' Deleted ' in res . data
2024-07-11 13:03:42 +00:00
def test_correct_header_detect ( client , live_server , measure_memory_usage ) :
2023-05-29 14:11:43 +00:00
# Like in https://github.com/dgtlmoon/changedetection.io/pull/1593
2024-02-07 19:58:21 +00:00
# Specify extra html that JSON is sometimes wrapped in - when using SockpuppetBrowser / Puppeteer / Playwrightetc
2023-05-29 14:11:43 +00:00
with open ( " test-datastore/endpoint-content.txt " , " w " ) as f :
f . write ( ' <html><body> { " hello " : 123, " world " : 123} ' )
# Add our URL to the import page
# Check weird casing is cleaned up and detected also
test_url = url_for ( ' test_endpoint ' , content_type = " aPPlication/JSon " , uppercase_headers = True , _external = True )
res = client . post (
2025-03-18 09:40:22 +00:00
url_for ( " imports.import_page " ) ,
2023-05-29 14:11:43 +00:00
data = { " urls " : test_url } ,
follow_redirects = True
)
assert b " 1 Imported " in res . data
wait_for_all_checks ( client )
2025-03-25 21:57:15 +00:00
res = client . get ( url_for ( " watchlist.index " ) )
2023-05-29 14:11:43 +00:00
2023-05-30 06:57:17 +00:00
# Fixed in #1593
assert b ' No parsable JSON found in this document ' not in res . data
2023-05-29 14:11:43 +00:00
2023-05-30 06:57:17 +00:00
res = client . get (
2025-03-18 09:40:22 +00:00
url_for ( " ui.ui_views.preview_page " , uuid = " first " ) ,
2023-05-30 06:57:17 +00:00
follow_redirects = True
)
2024-05-20 12:14:40 +00:00
assert b ' "hello": 123, ' in res . data
2024-10-05 14:32:28 +00:00
assert b ' "world": 123 ' in res . data
2023-05-29 14:11:43 +00:00
2025-03-18 09:40:22 +00:00
res = client . get ( url_for ( " ui.form_delete " , uuid = " all " ) , follow_redirects = True )
2023-05-29 14:11:43 +00:00
assert b ' Deleted ' in res . data
2024-07-11 13:03:42 +00:00
def test_check_jsonpath_ext_filter ( client , live_server , measure_memory_usage ) :
2022-10-09 14:12:45 +00:00
check_json_ext_filter ( ' json:$[?(@.status==Sold)] ' , client , live_server )
2024-07-11 13:03:42 +00:00
def test_check_jq_ext_filter ( client , live_server , measure_memory_usage ) :
2022-10-12 07:53:16 +00:00
if jq_support :
2024-06-21 11:31:03 +00:00
check_json_ext_filter ( ' jq:.[] | select(.status | contains( " Sold " )) ' , client , live_server )
2024-07-11 13:03:42 +00:00
def test_check_jqraw_ext_filter ( client , live_server , measure_memory_usage ) :
2024-06-21 11:31:03 +00:00
if jq_support :
check_json_ext_filter ( ' jq:.[] | select(.status | contains( " Sold " )) ' , client , live_server )
2025-02-07 21:19:23 +00:00
def test_jsonpath_BOM_utf8 ( client , live_server , measure_memory_usage ) :
from . . import html_tools
# JSON string with BOM and correct double-quoted keys
json_str = ' \ufeff { " name " : " José " , " emoji " : " 😊 " , " language " : " 中文 " , " greeting " : " Привет " } '
# See that we can find the second <script> one, which is not broken, and matches our filter
text = html_tools . extract_json_as_string ( json_str , " json:$.name " )
assert text == ' " José " '