def test_contact_group_discount(rf): default_price = 10 request, product = _init_test_for_product(rf, default_price) # Just to demonstrate that discounts can be created without products # and categories. This contact group gets $2 off from every product. product_discount_amount = 2 random_company = factories.create_random_company() contact_group = factories.get_default_customer_group() random_company.groups.add(contact_group) request.customer = random_company discount = Discount.objects.create( active=True, contact_group=contact_group, discount_amount_value=product_discount_amount) discount.shops.add(request.shop) assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount) new_product_price = 7 new_product = factories.create_product("test1", shop=request.shop, default_price=new_product_price) assert new_product.get_price_info(request).price == ( request.shop.create_price(new_product_price - product_discount_amount)) # Changing the request customer drops the $2 discount request.customer = factories.create_random_company() assert not request.customer.groups.filter(id=contact_group.pk).exists() assert product.get_price_info(request).price == request.shop.create_price(default_price) assert new_product.get_price_info(request).price == request.shop.create_price(new_product_price)
def test_company_contact_layout(): vc = _get_basic_view_config() company = factories.create_random_company() placeholder_name = "kissa" request = get_request() request.customer = company context = {"request": request} layout = vc.get_placeholder_layout(CompanyContactLayout, placeholder_name, context=context) assert isinstance(layout, CompanyContactLayout) help_text = layout.get_help_text({}) # Same help text with or without the context assert layout.get_help_text(context) == help_text # Invalid contexts for anon and person contact layouts assert vc.get_placeholder_layout(AnonymousContactLayout, placeholder_name, context=context) is None assert vc.get_placeholder_layout(PersonContactLayout, placeholder_name, context=context) is None # Valid contexts for contact layout assert vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context) is not None _add_plugin_and_test_save(vc, layout, placeholder_name, context) # Ok here we want to check that the plugin doesn't end up to the # contact placeholders contact_layout = vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context) _assert_empty_layout(contact_layout, placeholder_name)
def test_set_non_shop_member_customer(rf): """ Set some customer to the basket that is not member of the shop """ with override_settings(**CORE_BASKET_SETTINGS): shop = factories.get_shop(False) assert shop != factories.get_default_shop() user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") basket.customer = get_person_contact(user) assert basket.shop == factories.get_default_shop() person = factories.create_random_person() person.shops.add(shop) company = factories.create_random_company() company.add_to_shop(shop) for customer in [person, company]: with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, customer) assert exc.value.code == "invalid_customer_shop" assert basket.customer == get_person_contact(user)
def test_discount_for_companies(rf): default_price = 10 request, product = _init_test_for_product(rf, default_price) assert request.customer == AnonymousContact() random_company = factories.create_random_company() company_contact_group = random_company.get_default_group() product_discount_amount = 2 discount = Discount.objects.create( active=True, contact_group=company_contact_group, discount_amount_value=product_discount_amount) discount.shops.add(request.shop) assert product.get_price_info(request).price == request.shop.create_price(default_price) # Setting customer to request activates the discount request.customer = factories.create_random_company() assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount) # Using person contact as customer means no discount request.customer = factories.create_random_person() assert product.get_price_info(request).price == request.shop.create_price(default_price)
def test_customer_usage_limit(rf): default_price = 10 request, product = _init_test_for_product_without_basket(rf, default_price) shop = request.shop customers = [] for x in range(3): customers.append(factories.create_random_company(shop=shop)) discount_percentage = 0.20 coupon = CouponCode.objects.create(code="sUpErAle", active=True, usage_limit_customer=2) coupon.shops = [request.shop] discount = Discount.objects.create( active=True, product=product, coupon_code=coupon, discount_percentage=discount_percentage) discount.shops.add(request.shop) # Order product twice for each customer for customer in customers: for y in range(2): _create_order(request, customer, coupon, product, request.shop.create_price(8)) assert coupon.usages.count() == 6 # Each customer 2 orders # Any of the customers created shouldn't be allowed to # order more with this coupon code. for customer in customers: assert not CouponCode.is_usable(shop, coupon, customer) # New customer should still be able to order some new_customer = factories.create_random_person() assert CouponCode.is_usable(shop, coupon, new_customer) _create_order(request, new_customer, coupon, product, request.shop.create_price(8)) assert coupon.usages.count() == 7 # Set usage limit and the new customer shouldn't be able to use the code coupon.usage_limit = 7 coupon.save() assert not CouponCode.is_usable(request.shop, coupon, new_customer) _create_order(request, new_customer, coupon, product, request.shop.create_price(default_price)) assert coupon.usages.count() == 7 # One of the customer got refund refunded_customer = customers[0] order = refunded_customer.customer_orders.first() coupon_code_modifier = CouponCodeModule() coupon_code_modifier.clear_codes(order) assert coupon.usages.count() == 6 # New customer still doesn't able to create coupon new_customer = factories.create_random_person() assert CouponCode.is_usable(shop, coupon, new_customer) _create_order(request, new_customer, coupon, product, request.shop.create_price(8)) assert coupon.usages.count() == 7
def test_serialize_data(): """ Test contact dashboard views """ activate("en") shop = factories.get_default_shop() customer = factories.create_random_person("en") user = factories.create_random_user("en") user.set_password("1234") user.save() customer.user = user customer.default_billing_address = factories.create_random_address() customer.default_shipping_address = factories.create_random_address() customer.save() company = factories.create_random_company() company.default_billing_address = factories.create_random_address() company.default_shipping_address = factories.create_random_address() company.save() company.members.add(customer) product = factories.create_product("p1", shop, factories.get_default_supplier()) for basket_customer in [customer, company]: [factories.create_random_order(basket_customer, [product]) for order in range(3)] client = SmartClient() client.login(username=user.username, password="******") response = client.get(reverse("E-Commerce:gdpr_customer_dashboard")) assert response.status_code == 200 assert "My Data" in response.content.decode("utf-8") response = client.post(reverse("E-Commerce:gdpr_download_data")) assert response._headers["content-disposition"][0] == "Content-Disposition" assert response.status_code == 200 from E-Commerce.tasks.models import Task, TaskType from E-Commerce.gdpr.models import GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER response = client.post(reverse("E-Commerce:gdpr_anonymize_account")) assert response.status_code == 302 assert response.url.endswith(reverse("E-Commerce:index")) task_type = TaskType.objects.get(identifier=GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER, shop=shop) assert Task.objects.get(type=task_type, shop=shop) user.refresh_from_db() assert user.is_active is False refreshed_customer = PersonContact.objects.get(id=customer.id) assert refreshed_customer.is_active is False assert refreshed_customer.name == customer.name # nothing changed yet
def test_set_company_customer(rf): """ Set a company as the basket customer """ with override_settings(**CORE_BASKET_SETTINGS): user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") basket.customer = get_person_contact(user) person = factories.create_random_person() company = factories.create_random_company() # no orderer provided with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, company) assert exc.value.code == "invalid_orderer" assert basket.customer == get_person_contact(user) # orderer provided but not member of the company with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, company, person) assert exc.value.code == "orderer_not_company_member" assert basket.customer == get_person_contact(user) # orderer provided but user not member of the company company.members.add(person) with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, company, person) assert exc.value.code == "not_company_member" assert basket.customer == get_person_contact(user) # staff and admin can add any the company and orderer without being member of the company superuser = factories.create_random_user(is_superuser=True) staff = factories.create_random_user(is_staff=True) basket.shop.staff_members.add(staff) for user in [superuser, staff]: basket.customer = None basket.orderer = None request = apply_request_middleware(rf.get("/"), user=user) assert basket_commands.handle_set_customer(request, basket, company, person)["ok"] is True assert basket.customer == company assert basket.orderer == person
def test_anonymous_set_company_customer(rf): """ Set a company as the basket customer """ with override_settings(**CORE_BASKET_SETTINGS): user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") basket.customer = AnonymousContact() person = factories.create_random_person() company = factories.create_random_company() company.members.add(person) with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, company, person) assert exc.value.code == "not_company_member" assert basket.customer == AnonymousContact()
def test_discount_for_logged_in_contacts(rf): default_price = 10 request, product = _init_test_for_product(rf, default_price) assert request.customer == AnonymousContact() anon_default_group = AnonymousContact().get_default_group() product_discount_amount = 2 discount = Discount.objects.create( active=True, exclude_selected_contact_group=True, contact_group=anon_default_group, discount_amount_value=product_discount_amount) discount.shops.add(request.shop) assert product.get_price_info(request).price == request.shop.create_price(default_price) # Setting customer to request takes out the discount request.customer = factories.create_random_person() assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount) # Company as customer should work too request.customer = factories.create_random_company() assert product.get_price_info(request).price == request.shop.create_price(default_price - product_discount_amount)
def test_set_not_active_customer(rf): """ Set a not active customer to the basket """ with override_settings(**CORE_BASKET_SETTINGS): user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user) basket = get_basket(request, "basket") basket.customer = get_person_contact(user) person = factories.create_random_person() person.is_active = False person.save() company = factories.create_random_company() company.is_active = False company.save() for customer in [person, company]: with pytest.raises(ValidationError) as exc: basket_commands.handle_set_customer(request, basket, customer) assert exc.value.code == "invalid_customer" assert basket.customer == get_person_contact(user)
def test_index_view_with_contact_limitatons(): shop = factories.get_default_shop() password = "******" # Person 1 to test contact and person contact layouts person1 = factories.create_random_person(shop=shop) person1.user = factories.create_random_user() person1.user.set_password(password) person1.user.save() person1.save() # Person 2 to test company layout person2 = factories.create_random_person(shop=shop) person2.user = factories.create_random_user() person2.user.set_password(password) person2.user.save() person2.save() company = factories.create_random_company(shop=shop) company.members.add(person2) placeholder_name = "front_content" request = get_request() context = {"request": request} # Add plugin for anons vc = _get_basic_view_config(view_name="IndexView") anon_plugin_text = "This content is only for guests" layout = vc.get_placeholder_layout(AnonymousContactLayout, placeholder_name, context=context) _add_plugin_and_test_save(vc, layout, placeholder_name, context, anon_plugin_text) # Add plugin for contact vc = _get_basic_view_config(view_name="IndexView") context["request"].customer = person1 contact_plugin_text = "This content is only for users logged in" layout = vc.get_placeholder_layout(ContactLayout, placeholder_name, context=context) _add_plugin_and_test_save(vc, layout, placeholder_name, context, contact_plugin_text) # Add plugin for person contacts vc = _get_basic_view_config(view_name="IndexView") person_contact_plugin_text = "This content is only for person contacts" layout = vc.get_placeholder_layout(PersonContactLayout, placeholder_name, context=context) _add_plugin_and_test_save(vc, layout, placeholder_name, context, person_contact_plugin_text) # Add plugin for companies vc = _get_basic_view_config(view_name="IndexView") context["request"].customer = company company_plugin_text = "This content is only for companies" layout = vc.get_placeholder_layout(CompanyContactLayout, placeholder_name, context=context) _add_plugin_and_test_save(vc, layout, placeholder_name, context, company_plugin_text) c = SmartClient() # By default there is no user logged in soup = c.soup(reverse("E-Commerce:index")) page_content = soup.find("div", {"class": "page-content"}) page_content_text = page_content.text assert anon_plugin_text in page_content_text assert contact_plugin_text not in page_content_text assert person_contact_plugin_text not in page_content_text assert company_plugin_text not in page_content_text # Login as person1 user c = SmartClient() c.login(username=person1.user.username, password=password) soup = c.soup(reverse("E-Commerce:index")) page_content = soup.find("div", {"class": "page-content"}) page_content_text = page_content.text assert anon_plugin_text not in page_content_text assert contact_plugin_text in page_content_text assert person_contact_plugin_text in page_content_text assert company_plugin_text not in page_content_text # Login as person2 user which is linked to company c = SmartClient() c.login(username=person2.user.username, password=password) soup = c.soup(reverse("E-Commerce:index")) page_content = soup.find("div", {"class": "page-content"}) page_content_text = page_content.text assert anon_plugin_text not in page_content_text assert contact_plugin_text in page_content_text assert person_contact_plugin_text not in page_content_text assert company_plugin_text in page_content_text
def _get_edit_object_view(rf, view, model_name, object_id, user, shop, mode=None): data = { "model": model_name, "id": object_id } if mode: data["mode"] = mode request = apply_request_middleware(rf.get(reverse("E-Commerce_admin:edit"), data), user=user, shop=shop) return view(request) @pytest.mark.parametrize("creator_fn", [ lambda: factories.create_product("sku", factories.get_default_shop(), factories.get_default_supplier()), lambda: factories.create_random_person(), lambda: factories.create_random_company(), lambda: factories.create_random_order(customer=factories.create_random_person(), products=[ factories.create_product("p", factories.get_default_shop(), factories.get_default_supplier()) ]), lambda: factories.create_random_user(), ]) @pytest.mark.django_db def test_edit_object_view(rf, admin_user, creator_fn): shop = factories.get_default_shop() view = EditObjectView.as_view() object_instance = creator_fn() model = ".".join(ContentType.objects.get_for_model(object_instance).natural_key()) # correct shop response = _get_edit_object_view(rf, view, model, object_instance.id, admin_user, shop) assert response.status_code == 302
def test_create_order(admin_user, target_customer): with override_settings(**REQUIRED_SETTINGS): set_configuration() factories.create_default_order_statuses() shop = factories.get_default_shop() client = _get_client(admin_user) # Create basket for target customer payload = {"shop": shop.pk} target = orderer = get_person_contact(admin_user) if target_customer == "other_person": target = orderer = factories.create_random_person() payload["customer"] = target.pk elif target_customer == "company": target = factories.create_random_company() orderer = factories.create_random_person() payload.update({ "customer": target.pk, "orderer": orderer.pk }) target.members.add(orderer) response = client.post("/api/E-Commerce/basket/new/", payload) assert response.status_code == status.HTTP_201_CREATED basket_data = json.loads(response.content.decode("utf-8")) basket = Basket.objects.first() assert basket.key == basket_data["uuid"].split("-")[1] assert basket.customer == target assert basket.orderer == orderer shop_product = factories.get_default_shop_product() shop_product.default_price = TaxfulPrice(1, shop.currency) shop_product.save() # Add shop product to basket payload = {"shop_product": shop_product.id} response = client.post("/api/E-Commerce/basket/{}-{}/add/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_200_OK response_data = json.loads(response.content.decode("utf-8")) assert len(response_data["items"]) == 1 # Create order from basket response = client.post("/api/E-Commerce/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "errors" in response_data factories.get_default_payment_method() factories.get_default_shipping_method() response = client.post("/api/E-Commerce/basket/{}-{}/create_order/".format(shop.pk, basket.key), payload) assert response.status_code == status.HTTP_201_CREATED response_data = json.loads(response.content.decode("utf-8")) basket.refresh_from_db() assert basket.finished order = Order.objects.get(reference_number=response_data["reference_number"]) assert order.status == OrderStatus.objects.get_default_initial() assert order.payment_status == PaymentStatus.NOT_PAID assert order.shipping_status == ShippingStatus.NOT_SHIPPED assert not order.payment_method assert not order.shipping_method assert float(order.taxful_total_price_value) == 1 assert order.customer == target assert order.orderer == orderer assert order.creator == admin_user assert not order.billing_address assert not order.shipping_address
def test_serialize_data(): """ Test that contact data is serialized """ activate("en") shop = factories.get_default_shop() customer = factories.create_random_person("en") user = factories.create_random_user("en") customer.user = user customer.default_billing_address = factories.create_random_address() customer.default_shipping_address = factories.create_random_address() customer.save() company = factories.create_random_company() company.default_billing_address = factories.create_random_address() company.default_shipping_address = factories.create_random_address() company.save() company.members.add(customer) product = factories.create_product("p1", shop, factories.get_default_supplier()) orders = [] core_baskets = [] front_baskets = [] for basket_customer in [customer, company]: orders.extend([factories.create_random_order(basket_customer, [product]) for order in range(3)]) front_baskets.append( StoredBasket.objects.create( key=uuid4().hex, shop=shop, customer=basket_customer, orderer=customer, creator=customer.user, currency=shop.currency, data={"items": []}, prices_include_tax=shop.prices_include_tax ) ) core_baskets.append( Basket.objects.create( key=uuid4().hex, shop=shop, customer=basket_customer, orderer=customer, creator=customer.user, currency=shop.currency, data={"items": []}, prices_include_tax=shop.prices_include_tax ) ) person_data = GDPRPersonContactSerializer(customer).data assert person_data["name"] == customer.name assert person_data["phone"] == customer.phone assert person_data["default_billing_address"]["street"] == customer.default_billing_address.street assert person_data["default_shipping_address"]["street"] == customer.default_shipping_address.street assert person_data["user"]["id"] == customer.user.id assert person_data["user"]["username"] == customer.user.username assert person_data["company_memberships"][0]["name"] == company.name assert person_data["company_memberships"][0]["id"] == company.id assert len(person_data["orders"]) == 3 assert len(person_data["saved_baskets"]) == 1 assert len(person_data["baskets"]) == 1
def test_anonymize_contact(): """ Test that contact are anonymized """ activate("en") shop = factories.get_default_shop() anonymizer = Anonymizer() customer = factories.create_random_person("en") user = factories.create_random_user("en") customer.user = user customer.default_billing_address = factories.create_random_address() customer.default_shipping_address = factories.create_random_address() customer.save() company = factories.create_random_company() company.default_billing_address = factories.create_random_address() company.default_shipping_address = factories.create_random_address() company.save() company.members.add(customer) product = factories.create_product("p1", shop, factories.get_default_supplier()) orders = [] core_baskets = [] front_baskets = [] for basket_customer in [customer, company]: orders.extend([factories.create_random_order(basket_customer, [product]) for order in range(3)]) front_baskets.append( StoredBasket.objects.create( key=uuid4().hex, shop=shop, customer=basket_customer, orderer=customer, creator=customer.user, currency=shop.currency, data={"items": []}, prices_include_tax=shop.prices_include_tax ) ) core_baskets.append( Basket.objects.create( key=uuid4().hex, shop=shop, customer=basket_customer, orderer=customer, creator=customer.user, currency=shop.currency, data={"items": []}, prices_include_tax=shop.prices_include_tax ) ) anonymized_person = PersonContact.objects.get(id=customer.id) anonymizer.anonymize_person(anonymized_person) anonymized_person.refresh_from_db() assert anonymized_person.first_name != customer.first_name assert anonymized_person.last_name != customer.last_name assert anonymized_person.email != customer.email assert anonymized_person.phone != customer.phone assert anonymized_person.default_billing_address.street != customer.default_billing_address.street assert anonymized_person.default_billing_address.city != customer.default_billing_address.city anonymized_company = CompanyContact.objects.get(id=company.id) anonymizer.anonymize_company(anonymized_company) anonymized_company.refresh_from_db() assert anonymized_company.tax_number != company.tax_number assert anonymized_company.email != company.email assert anonymized_company.phone != company.phone assert anonymized_company.default_billing_address.street != company.default_billing_address.street assert anonymized_company.default_billing_address.city != company.default_billing_address.city for created_order in orders: order = Order.objects.get(id=created_order.id) assert order.phone != created_order.phone assert order.ip_address != created_order.ip_address assert order.shipping_address.street != created_order.shipping_address.street assert order.billing_address.street != created_order.billing_address.street for front_basket in front_baskets: stored_basket = StoredBasket.objects.get(id=front_basket.id) assert stored_basket.data is None for core_basket in core_baskets: basket = Basket.objects.get(id=core_basket.id) assert basket.data is None anonymized_user = get_user_model().objects.get(id=user.id) anonymizer.anonymize_user(anonymized_user) anonymized_user.refresh_from_db() assert user.username != anonymized_user.username assert user.first_name != anonymized_user.first_name assert user.last_name != anonymized_user.last_name
def test_xtheme_edit_front(admin_user, browser, live_server, settings): browser = initialize_admin_browser_test(browser, live_server, settings) # Login to admin as admin user browser.visit(live_server + "/") wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) # Start edit click_element(browser, ".xt-edit-toggle button[type='submit']") # Add some content only visible for person contacts person_contact_text_content = "This text is shown for person contacts only!" _edit_layout( browser, "front_content", "#xt-ph-front_content-xtheme-person-contact-layout", person_contact_text_content) browser.find_by_css("#admin-tools-menu li.dropdown").click() browser.find_by_css("a[href='/force-anonymous-contact/']").first.click() ## Add some content only visible for anonymous contacts anonymous_contact_text_content = "This text is shown for guests only!" _edit_layout( browser, "front_content", "#xt-ph-front_content-xtheme-anonymous-contact-layout", anonymous_contact_text_content) browser.find_by_css("#admin-tools-menu li.dropdown").click() browser.find_by_css("a[href='/force-company-contact/']").first.click() ### Add some content only visible for company contacts company_contact_text_content = "This text is shown for company contacts only!" _edit_layout( browser, "front_content", "#xt-ph-front_content-xtheme-company-contact-layout", company_contact_text_content) # Close edit click_element(browser, ".xt-edit-toggle button[type='submit']") # Logout click_element(browser, "div.top-nav i.menu-icon.fa.fa-user") click_element(browser, "a[href='/logout/']") # Go to home and check content for anonymous contacts browser.visit(live_server + "/") wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) wait_until_condition(browser, lambda x: x.is_text_present(anonymous_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(person_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(company_contact_text_content)) # Create user login and got check the content for person contact user = factories.create_random_user() password = "******" user.set_password(password) user.save() click_element(browser, "#login-dropdown") browser.fill("username", user.username) browser.fill("password", password) browser.find_by_css("ul.login button[type='submit']").click() wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) wait_until_condition(browser, lambda x: x.is_text_present(person_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(anonymous_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(company_contact_text_content)) # Logout click_element(browser, "div.top-nav i.menu-icon.fa.fa-user") click_element(browser, "a[href='/logout/']") # Create person contact to company and re-login and check the content for companies company = factories.create_random_company() company.members.add(get_person_contact(user)) click_element(browser, "#login-dropdown") browser.fill("username", user.username) browser.fill("password", password) browser.find_by_css("ul.login button[type='submit']").click() wait_until_condition(browser, lambda x: x.is_text_present("Welcome to Default!")) wait_until_condition(browser, lambda x: x.is_text_present(company_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(anonymous_contact_text_content)) wait_until_condition(browser, lambda x: not x.is_text_present(person_contact_text_content))