277 lines
11 KiB
Python
277 lines
11 KiB
Python
# Copyright 2026 Criptomart
|
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
|
|
|
from odoo import fields
|
|
from odoo.tests import HttpCase, tagged
|
|
|
|
from odoo.addons.membership.tests.common import TestMembershipCommon
|
|
|
|
|
|
@tagged("post_install", "-at_install")
|
|
class TestWebsiteMembershipAssociate(HttpCase, TestMembershipCommon):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.website = cls.env.ref("website.default_website")
|
|
cls.country_us = cls.env.ref("base.us")
|
|
cls.country_be = cls.env.ref("base.be")
|
|
|
|
cls.membership_1.write({"website_published": True})
|
|
cls.partner_1.write(
|
|
{
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_us.id,
|
|
}
|
|
)
|
|
invoice = cls.partner_1.create_membership_invoice(cls.membership_1, 75.0)
|
|
invoice.action_post()
|
|
cls.env["account.payment.register"].with_context(
|
|
active_model="account.move", active_ids=invoice.ids
|
|
).create(
|
|
{
|
|
"amount": 86.25,
|
|
"payment_method_line_id": cls.inbound_payment_method_line.id,
|
|
}
|
|
)._create_payments()
|
|
cls.partner_1._compute_membership_state()
|
|
|
|
cls.associate = cls.env["res.partner"].create(
|
|
{
|
|
"name": "Associate Paid",
|
|
"associate_member": cls.partner_1.id,
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_be.id,
|
|
"website_description": "Sustainable farming",
|
|
}
|
|
)
|
|
|
|
cls.partner_2.write(
|
|
{
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_us.id,
|
|
}
|
|
)
|
|
cls.associate_free = cls.env["res.partner"].create(
|
|
{
|
|
"name": "Associate Free",
|
|
"associate_member": cls.partner_2.id,
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_us.id,
|
|
}
|
|
)
|
|
|
|
def test_host_membership_state_is_paid(self):
|
|
self.assertEqual(self.partner_1.membership_state, "paid")
|
|
|
|
def test_members_page_lists_host_and_associate(self):
|
|
response = self.url_open("/members")
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(self.partner_1.name, response.text)
|
|
self.assertIn(self.associate.name, response.text)
|
|
|
|
def test_membership_filter_includes_associate(self):
|
|
response = self.url_open("/members/association/%d" % self.membership_1.id)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(self.partner_1.name, response.text)
|
|
self.assertIn(self.associate.name, response.text)
|
|
|
|
def test_free_membership_filter_includes_associate(self):
|
|
response = self.url_open("/members/association/free")
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(self.partner_2.name, response.text)
|
|
self.assertIn(self.associate_free.name, response.text)
|
|
|
|
def test_country_filter_counts_associate(self):
|
|
response = self.url_open("/members/country/%d" % self.country_be.id)
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(self.associate.name, response.text)
|
|
self.assertNotIn(self.partner_1.name, response.text)
|
|
self.assertNotIn(self.partner_2.name, response.text)
|
|
self.assertNotIn(self.associate_free.name, response.text)
|
|
|
|
def test_search_finds_associate(self):
|
|
response = self.url_open("/members?search=Sustainable+farming")
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertIn(self.associate.name, response.text)
|
|
self.assertNotIn(self.partner_1.name, response.text)
|
|
|
|
def test_published_companies_map_includes_associate(self):
|
|
host_line = self.partner_1.member_lines[0]
|
|
companies = host_line._get_published_companies(limit=2000)
|
|
self.assertIn(self.partner_1.id, companies)
|
|
self.assertIn(self.associate.id, companies)
|
|
|
|
|
|
@tagged("post_install", "-at_install")
|
|
class TestWebsiteMembershipAssociatePagination(HttpCase, TestMembershipCommon):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.website = cls.env.ref("website.default_website")
|
|
cls.country_es = cls.env.ref("base.es")
|
|
cls.membership_1.write({"website_published": True})
|
|
|
|
host_vals = [
|
|
{
|
|
"name": "Host Page %d" % i,
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_es.id,
|
|
}
|
|
for i in range(20)
|
|
]
|
|
cls.paginated_hosts = cls.env["res.partner"].create(host_vals)
|
|
invoices = cls.paginated_hosts.create_membership_invoice(
|
|
cls.membership_1, 75.0
|
|
)
|
|
invoices.action_post()
|
|
cls.env["account.payment.register"].with_context(
|
|
active_model="account.move", active_ids=invoices.ids
|
|
).create(
|
|
{
|
|
"amount": sum(invoices.mapped("amount_total")),
|
|
"payment_method_line_id": cls.inbound_payment_method_line.id,
|
|
}
|
|
)._create_payments()
|
|
cls.paginated_hosts._compute_membership_state()
|
|
|
|
associate_vals = [
|
|
{
|
|
"name": "Associate Page %d" % i,
|
|
"associate_member": cls.paginated_hosts[i].id,
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_es.id,
|
|
}
|
|
for i in range(20)
|
|
]
|
|
cls.paginated_associates = cls.env["res.partner"].create(associate_vals)
|
|
|
|
def test_pagination_hosts_plus_associates(self):
|
|
response = self.url_open("/members/association/%d" % self.membership_1.id)
|
|
self.assertEqual(response.status_code, 200)
|
|
# Page 1 contains all 20 hosts plus their 20 associates.
|
|
self.assertIn("Host Page 0", response.text)
|
|
self.assertIn("Host Page 19", response.text)
|
|
self.assertIn("Associate Page 0", response.text)
|
|
self.assertIn("Associate Page 19", response.text)
|
|
# No pagination placeholder from a second page is expected.
|
|
self.assertNotIn("Host Page 20", response.text)
|
|
self.assertNotIn("Associate Page 20", response.text)
|
|
|
|
|
|
@tagged("post_install", "-at_install")
|
|
class TestMembershipLineAssociate(TestMembershipCommon):
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.country_us = cls.env.ref("base.us")
|
|
cls.country_be = cls.env.ref("base.be")
|
|
|
|
cls.membership_1.write({"website_published": True})
|
|
cls.partner_1.write(
|
|
{
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_us.id,
|
|
"website_description": "Host description",
|
|
}
|
|
)
|
|
invoice = cls.partner_1.create_membership_invoice(cls.membership_1, 75.0)
|
|
invoice.action_post()
|
|
cls.env["account.payment.register"].with_context(
|
|
active_model="account.move", active_ids=invoice.ids
|
|
).create(
|
|
{
|
|
"amount": invoice.amount_total,
|
|
"payment_method_line_id": cls.inbound_payment_method_line.id,
|
|
}
|
|
)._create_payments()
|
|
cls.partner_1._compute_membership_state()
|
|
|
|
cls.associate = cls.env["res.partner"].create(
|
|
{
|
|
"name": "Associate Paid",
|
|
"associate_member": cls.partner_1.id,
|
|
"website_published": True,
|
|
"is_company": True,
|
|
"country_id": cls.country_be.id,
|
|
"website_description": "Sustainable farming",
|
|
}
|
|
)
|
|
|
|
def _base_domain(self):
|
|
today = fields.Date.today()
|
|
return [
|
|
("partner.website_published", "=", True),
|
|
("state", "=", "paid"),
|
|
("date_to", ">=", today),
|
|
("date_from", "<=", today),
|
|
("membership_id", "in", self.membership_1.ids),
|
|
]
|
|
|
|
def test_search_excludes_host_when_only_associate_matches_without_context(self):
|
|
domain = self._base_domain()
|
|
domain += [
|
|
"|",
|
|
("partner.name", "ilike", "Sustainable farming"),
|
|
("partner.website_description", "ilike", "Sustainable farming"),
|
|
]
|
|
lines = self.env["membership.membership_line"].search(domain)
|
|
self.assertNotIn(self.partner_1.id, lines.partner.ids)
|
|
|
|
def test_search_includes_host_when_associate_name_matches(self):
|
|
domain = self._base_domain()
|
|
domain += [
|
|
"|",
|
|
("partner.name", "ilike", "Sustainable farming"),
|
|
("partner.website_description", "ilike", "Sustainable farming"),
|
|
]
|
|
lines = (
|
|
self.env["membership.membership_line"]
|
|
.with_context(include_associate_members=True)
|
|
.search(domain)
|
|
)
|
|
self.assertIn(self.partner_1.id, lines.partner.ids)
|
|
|
|
def test_search_includes_host_when_associate_country_matches(self):
|
|
domain = self._base_domain()
|
|
domain.append(("partner.country_id", "=", self.country_be.id))
|
|
lines = (
|
|
self.env["membership.membership_line"]
|
|
.with_context(include_associate_members=True)
|
|
.search(domain)
|
|
)
|
|
self.assertIn(self.partner_1.id, lines.partner.ids)
|
|
|
|
def test_get_associate_partners_filters_by_country(self):
|
|
MembershipLine = self.env["membership.membership_line"]
|
|
match = MembershipLine._get_associate_partners(
|
|
(self.partner_1.id,), country_id=self.country_be.id
|
|
)
|
|
self.assertEqual(match, self.associate)
|
|
no_match = MembershipLine._get_associate_partners(
|
|
(self.partner_1.id,), country_id=self.country_us.id
|
|
)
|
|
self.assertFalse(no_match)
|
|
|
|
def test_get_associate_partners_filters_by_search(self):
|
|
MembershipLine = self.env["membership.membership_line"]
|
|
match = MembershipLine._get_associate_partners(
|
|
(self.partner_1.id,), post_name="Sustainable"
|
|
)
|
|
self.assertEqual(match, self.associate)
|
|
no_match = MembershipLine._get_associate_partners(
|
|
(self.partner_1.id,), post_name="Nonexistent"
|
|
)
|
|
self.assertFalse(no_match)
|
|
|
|
def test_published_companies_includes_associate(self):
|
|
host_line = self.partner_1.member_lines[0]
|
|
companies = host_line._get_published_companies(limit=2000)
|
|
self.assertIn(self.partner_1.id, companies)
|
|
self.assertIn(self.associate.id, companies)
|