"
""
)
neuf = cow.repair_anchor(
copie, ARCH_MODULE, "//t[@t-set='contactus_form_values']"
)
hote = etree.fromstring(neuf.encode("utf-8")).xpath(
"//t[@t-call='website.layout']"
)[0]
noms = [e.get("t-set") or e.get("id") for e in hote]
self.assertEqual(
["deja_la", "contactus_form_values", "wrap"], noms, neuf
)
def test_it_keeps_the_page_written_by_the_customer(self):
# C'est tout l'enjeu : réinitialiser la vue rendrait la page
# fonctionnelle et effacerait son contenu.
neuf = cow.repair_anchor(
ARCH_COPIE, ARCH_MODULE, "//t[@t-set='contactus_form_values']"
)
self.assertIn("Parlons de votre projet", neuf)
def test_it_refuses_when_the_host_element_has_no_twin(self):
# Mieux vaut une réparation refusée qu'un bloc posé au hasard au
# milieu de la page de quelqu'un.
etrangere = ""
self.assertIsNone(
cow.repair_anchor(
etrangere, ARCH_MODULE, "//t[@t-set='contactus_form_values']"
)
)
def test_it_refuses_when_the_module_has_no_anchor_either(self):
self.assertIsNone(
cow.repair_anchor(ARCH_COPIE, ARCH_COPIE, "//t[@t-set='absent']")
)
def test_it_refuses_an_unparsable_arch(self):
self.assertIsNone(cow.repair_anchor("", "fr_CA": ""})),
["en_US", "fr_CA"],
)
def test_the_query_never_pins_one_language(self):
# C'est ICI que le défaut est né : `arch_db->>'en_US'` ramenait
# une seule langue, l'audit déclarait la vue saine et /contact
# restait en 500 parce que le site rend en fr_CA. La requête doit
# ramener l'OBJET entier.
requete = cow.arch_expr(jsonb=True)
self.assertNotIn("en_US", requete)
self.assertNotIn("->>", requete)
self.assertIn("arch_db", requete)
def test_a_varchar_column_is_wrapped_as_one_nameless_language(self):
# Une seule forme en aval : le reste du code n'a pas à savoir si
# la version traduit l'arch ou non.
requete = cow.arch_expr(jsonb=False)
self.assertIn("json_build_object", requete)
def test_a_plain_string_is_the_language_less_case(self):
self.assertEqual(cow.langs_of(""), {"": ""})
def test_a_non_string_value_is_ignored(self):
self.assertEqual(
cow.langs_of({"en_US": "", "x": 3}), {"en_US": ""}
)
def test_the_xpath_of_a_child_is_read_from_any_language(self):
# Les xpath ne sont pas traduits : n'importe quelle langue suffit.
self.assertEqual(
cow.anchors_wanted(cow.any_lang({"fr_CA": ARCH_ENFANT})),
["//t[@t-set='contactus_form_values']"],
)
class TestTheSqlItWrites(unittest.TestCase):
def test_it_writes_all_the_languages_in_one_update(self):
# Deux UPDATE sur la même vue et le second effacerait le premier ;
# un seul portant une langue laisserait l'autre cassée.
sql = cow.write_arch_sql(
7, {"en_US": "", "fr_CA": ""}, jsonb=True
)
self.assertEqual(1, sql.count("UPDATE"), sql)
self.assertIn("en_US", sql)
self.assertIn("fr_CA", sql)
self.assertIn("", sql)
self.assertIn("", sql)
self.assertIn("WHERE id = 7", sql)
def test_the_varchar_case_writes_the_text_itself(self):
sql = cow.write_arch_sql(7, {"": ""}, jsonb=False)
self.assertNotIn("jsonb_build_object", sql)
self.assertIn("", sql)
def test_both_branches_survive_an_apostrophe(self):
# La 16 stocke en varchar, la 17 et la 18 en jsonb : les DEUX
# chemins écrivent, et n'éprouver que l'un laisse l'autre casser
# au premier attribut cité.
arch = ""
for jsonb, langues in ((True, {"en_US": arch}), (False, {"": arch})):
with self.subTest(jsonb=jsonb):
sql = cow.write_arch_sql(7, langues, jsonb=jsonb)
self.assertIn("$elcow$" + arch + "$elcow$", sql)
class TestTheReport(unittest.TestCase):
def rapport(self):
return {
"database": "essai",
"jsonb": True,
"views": [
{
"id": 1228,
"key": "website.contactus",
"anchors": [{"enfant": 2782, "expr": "//t[@t-set='x']"}],
"calls": ["website.company_description"],
}
],
}
def test_a_clean_database_says_so(self):
texte = "\n".join(
cow.render({"database": "x", "jsonb": True, "views": []}, [])
)
self.assertIn("✅", texte)
def test_it_names_the_view_the_child_and_the_template(self):
texte = "\n".join(cow.render(self.rapport(), []))
self.assertIn("1228", texte)
self.assertIn("2782", texte)
self.assertIn("website.company_description", texte)
def test_it_warns_that_removing_a_call_removes_a_block(self):
# Le message passe par `t()` : le comparer à un mot anglais en
# dur le fait tomber dès qu'on le traduit. On demande la MÊME
# traduction que le code, ce qui éprouve l'avertissement sans
# épouser une langue.
gestes = [(1228, "k", "t-call", "website.company_description", "SQL")]
texte = "\n".join(cow.render(self.rapport(), gestes))
self.assertIn(
cow.t("Removing a call removes its block from the page."), texte
)
def test_it_stays_silent_about_blocks_when_nothing_is_removed(self):
gestes = [(1228, "k", "anchor", "//t", "SQL")]
texte = "\n".join(cow.render(self.rapport(), gestes))
self.assertNotIn(
cow.t("Removing a call removes its block from the page."), texte
)
def test_it_says_when_a_repair_is_out_of_reach(self):
gestes = [(1228, "k", "anchor-impossible", "//t", None)]
texte = "\n".join(cow.render(self.rapport(), gestes))
self.assertIn("1", texte)
self.assertIn("⚠", texte)
if __name__ == "__main__":
unittest.main()