def test_comment_visibility(admin_user): shop = factories.get_default_shop() admin_contact = get_person_contact(admin_user) staff_user = factories.create_random_user("en", is_staff=True) staff_contact = get_person_contact(staff_user) shop.staff_members.add(staff_user) normal_user = factories.create_random_user("en") normal_contact = get_person_contact(normal_user) task_type = TaskType.objects.create(name="Request", shop=shop) task = create_task(shop, admin_contact, task_type, "my task") task.comment(admin_contact, "This is only visibile for super users", TaskCommentVisibility.ADMINS_ONLY) task.comment(staff_contact, "This is only visibile for staff only", TaskCommentVisibility.STAFF_ONLY) task.comment(normal_contact, "This is visibile for everyone", TaskCommentVisibility.PUBLIC) # admin see all comments assert task.comments.for_contact(admin_contact).count() == 3 # staff see all public + staff only assert task.comments.for_contact(staff_contact).count() == 2 # normal contact see all public assert task.comments.for_contact(normal_contact).count() == 1 # anonymous contact see all public assert task.comments.for_contact(AnonymousContact()).count() == 1
def test_order_creator_account_manager(): company = create_random_company() shop = get_shop(identifier="random-shop", enabled=True) source = seed_source(create_random_user(), shop) source.customer = company source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) creator = OrderCreator() order = creator.create_order(source) assert order.account_manager is None # Company contact doesn't have account manager field person = create_random_person() person.account_manager = create_random_person() person.save() source = seed_source(create_random_user(), shop) source.customer = person source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) creator = OrderCreator() order = creator.create_order(source) assert order.account_manager is not None assert order.account_manager == person.account_manager with pytest.raises(ProtectedError): person.account_manager.delete()
def test_get_shop(rf, get_shop_fn): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): activate("en") shop1 = Shop.objects.create(identifier="shop1", status=ShopStatus.ENABLED) shop2 = Shop.objects.create(identifier="shop2", status=ShopStatus.ENABLED) normal_user = factories.create_random_user() staff_user = factories.create_random_user(is_staff=True) request = apply_request_middleware(rf.post("/"), user=normal_user, skip_session=True) # user not staff assert get_shop_fn(request) is None # staff user now with pytest.raises(PermissionDenied) as exc: request = apply_request_middleware(rf.post("/"), user=staff_user) assert exc.value == "You are not a staff member of this shop" # no shop set assert get_shop_fn(request) is None # adds the user to a shop shop1.staff_members.add(staff_user) request = apply_request_middleware(rf.post("/"), user=staff_user, skip_session=True) assert get_shop_fn(request) == shop1 # adds the user to another shop shop2.staff_members.add(staff_user) # still the first shop as we do not set any assert get_shop_fn(request) == shop1 for shop in [shop1, shop2]: request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) assert get_shop_fn(request) == shop
def test_stripe_checkout_phase_with_saved_card_exception(rf, stripe_payment_processor): shop = factories.get_default_shop() user = factories.create_random_user() contact = get_person_contact(user) request = apply_request_middleware(rf.post("/"), shop=shop, customer=contact) def raise_stripe_exc(*args, **kwargs): raise stripe.StripeError("DUMMY") with mock.patch("stripe.Customer.retrieve", new=raise_stripe_exc): service = stripe_payment_processor.create_service( "stripe", shop=request.shop, tax_class=factories.get_default_tax_class(), enabled=True) StripeCustomer.objects.create(contact=contact, customer_token="123") checkout_phase = StripeCheckoutPhase(request=request, service=service) assert not checkout_phase.is_valid() context = checkout_phase.get_context_data() assert context["stripe"] assert not context.get("stripe_customer_data") request.method = "POST" request.POST = {} checkout_phase.get_success_url = lambda: reverse("shuup_admin:home") checkout_phase.post(request) assert not checkout_phase.is_valid()
def test_stripe_checkout_phase_with_saved_card(rf, stripe_payment_processor): shop = factories.get_default_shop() user = factories.create_random_user() contact = get_person_contact(user) request = apply_request_middleware(rf.post("/"), shop=shop, customer=contact) def return_stripe_mock_data(*args, **kwargs): return StripedData(**CUSTOMER_MOCK_DATA) with mock.patch("stripe.Customer.retrieve", new=return_stripe_mock_data): service = stripe_payment_processor.create_service( "stripe", shop=request.shop, tax_class=factories.get_default_tax_class(), enabled=True) StripeCustomer.objects.create(contact=contact, customer_token="123") checkout_phase = StripeCheckoutPhase(request=request, service=service) assert not checkout_phase.is_valid() context = checkout_phase.get_context_data() assert context["stripe"] request.method = "POST" request.POST = { "stripeCustomer": "1234" } checkout_phase.get_success_url = lambda: reverse("shuup_admin:home") checkout_phase.post(request) assert checkout_phase.is_valid() # We should be valid now assert request.session # And things should've been saved into the session checkout_phase.process() # And this should do things to the basket assert request.basket.payment_data["stripe"]["customer"]
def _test_happy_hours_list_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) happy_hour = HappyHour.objects.create(name="After Work %s" % index) happy_hour.shops = [shop] view_func = HappyHourListView.as_view() request = apply_request_middleware( rf.get("/", { "jq": json.dumps({"perPage": 100, "page": 1}) }), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 200 view_instance = HappyHourListView() view_instance.request = request assert request.shop == shop assert view_instance.get_queryset().count() == 1 data = json.loads(view_instance.get(request).content.decode("UTF-8")) assert len(data["items"]) == 1
def _test_happy_hours_delete_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) happy_hour_name = "The Hour %s" % index happy_hour = HappyHour.objects.create(name=happy_hour_name) happy_hour.shops = [shop] extra_happy_hour= HappyHour.objects.create(name="Extra Hour %s" % index) extra_happy_hour.shops = [shop] assert HappyHour.objects.filter(name=happy_hour_name).exists() view_func = HappyHourDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request, pk=happy_hour.pk) if hasattr(response, "render"): response.render() assert response.status_code == 302 assert not HappyHour.objects.filter(name=happy_hour_name).exists() # Make sure that this staff can't remove other people discounts other_exceptions = HappyHour.objects.exclude(shops=shop) exception_count = other_exceptions.count() for coupon in other_exceptions: view_func = HappyHourDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) with pytest.raises(Http404): response = view_func(request, pk=coupon.pk) if hasattr(response, "render"): response.render() assert exception_count == HappyHour.objects.exclude(shops=shop).count()
def test_force_views_only_for_staff(rf): shop = factories.get_default_shop() user = factories.create_random_user(is_staff=True) person_contact = get_person_contact(user) # Start forcing. There shouldn't be any changes to # request customer due calling the force functions since # those just do the redirect in case the current is user # is not shop staff. request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact _call_force_view(request, force_anonymous_contact) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact _call_force_view(request, force_person_contact) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact _call_force_view(request, force_company_contact) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact assert get_company_contact(user) is None
def test_update_injection(): shop = factories.get_default_shop() client = SmartClient() index_url = reverse("shuup:index") page = ensure_gdpr_privacy_policy(shop) shop_gdpr = GDPRSettings.get_for_shop(shop) shop_gdpr.enabled = True shop_gdpr.privacy_policy = page shop_gdpr.save() assert_update(client, index_url, False) # nothing consented in past, should not show user = factories.create_random_user("en") password = "******" user.set_password(password) user.save() client.login(username=user.username, password=password) assert_update(client, index_url, False) # no consent given, should not be visible create_user_consent_for_all_documents(shop, user) assert_update(client, index_url, False) with reversion.create_revision(): page.save() assert not is_documents_consent_in_sync(shop, user) assert_update(client, index_url, True) # consent client.get(reverse("shuup:gdpr_policy_consent", kwargs=dict(page_id=page.pk))) assert is_documents_consent_in_sync(shop, user) assert_update(client, index_url, False)
def test_category_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/categories/new") wait_until_condition(browser, lambda x: x.is_text_present("Add a new product category"), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") wait_until_condition(browser, lambda x: not x.is_element_present_by_css(".shepherd-button")) wait_until_condition(browser, lambda x: is_tour_complete(shop, "category", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/categories/new") wait_until_condition(browser, lambda x: not x.is_text_present("Add a new product category")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") assert is_tour_complete(shop2, "category", user) is False
def test_reset_admin_user_password(client): get_default_shop() user = factories.create_random_user("en", is_staff=True, is_active=True, email=REGULAR_USER_EMAIL) user.set_password(REGULAR_USER_PASSWORD) user.save(update_fields=("password",)) assert len(mail.outbox) == 0 response = client.post(reverse("shuup_admin:request_password"), data={ "email": user.email }) assert response.status_code == 302 assert response.get("location") assert response.get("location").endswith(reverse("shuup_admin:login")) assert len(mail.outbox) == 1 email_content = mail.outbox[0].body url = email_content[email_content.find("http"):] _, _, _, _, _, uid, token, _ = url.split("/") new_password = "******" response = client.post(reverse("shuup_admin:recover_password", kwargs=dict(uidb64=uid, token=token)), data={ "new_password1": new_password, "new_password2": new_password }) assert response.status_code == 302 assert response.get("location") assert response.get("location").endswith(reverse("shuup_admin:login")) assert len(mail.outbox) == 1 user.refresh_from_db() assert user.check_password(new_password)
def test_product_edit_view_multipleshops(rf): """ Check whether a staff user from Shop A can see the product from Shop B when the staff user is only attached to Shop A """ with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): shop1 = get_default_shop() shop2 = get_new_shop(identifier="shop2", domain="shop2", name="Shop 2") shop2_staff = create_random_user(is_staff=True) shop2.staff_members.add(shop2_staff) product = create_product("shop1-product", shop=shop1) shop_product = product.get_shop_instance(shop1) request = apply_request_middleware(rf.get("/", HTTP_HOST=shop2.domain), user=shop2_staff) view_func = ProductEditView.as_view() with pytest.raises(Http404): view_func(request, pk=shop_product.pk) view_func = ProductListView.as_view() payload = {"jq": json.dumps({"perPage": 100, "page": 1}), "shop": shop2.pk} request = apply_request_middleware(rf.get("/", payload, HTTP_HOST=shop2.domain), user=shop2_staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) assert len(data["items"]) == 0
def test_coupon_creation_for_supplier(rf, admin_user): """ To make things little bit more simple let's use only english as a language. """ shop = get_default_shop() supplier = Supplier.objects.create(identifier=admin_user.username) another_superuser = create_random_user(is_superuser=True, is_staff=True) supplier2 = Supplier.objects.create(identifier=another_superuser.username) supplier_provider = "shuup.testing.supplier_provider.UsernameSupplierProvider" with override_settings(LANGUAGES=[("en", "en")]): with override_settings(SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider): view = CouponEditView.as_view() data = { "code": "OK", "active": True, "shop": shop.pk } coupons_before = Coupon.objects.count() request = apply_request_middleware(rf.post("/", data=data), user=admin_user) assert get_supplier(request) == supplier response = view(request, pk=None) assert response.status_code in [200, 302] assert Coupon.objects.count() == (coupons_before + 1) new_coupon = Coupon.objects.filter(supplier=supplier).first() assert new_coupon # Another superuser shouldn't see this campaign request = apply_request_middleware(rf.post("/", data=data), user=another_superuser) assert get_supplier(request) == supplier2 with pytest.raises(Http404): response = view(request, pk=new_coupon.pk)
def test_company_contact_for_shop_staff(rf, admin_user): company_contact = get_company_contact(admin_user) assert company_contact is None shop = factories.get_default_shop() # Let's create shop for the shop staff company_contact = get_company_contact_for_shop_staff(shop, admin_user) company_contact = get_company_contact_for_shop_staff(shop, admin_user) assert company_contact is not None # Let's create second staff member to make sure all good with # creating company contact for shop staff. new_staff_user = factories.create_random_user() with pytest.raises(AssertionError): get_company_contact_for_shop_staff(shop, new_staff_user) new_staff_user.is_staff = True new_staff_user.save() with pytest.raises(AssertionError): # Since the new staff is not in shop members. The admin user # passed since he is also superuser. get_company_contact_for_shop_staff(shop, new_staff_user) shop.staff_members.add(new_staff_user) assert company_contact == get_company_contact_for_shop_staff(shop, new_staff_user) # Make sure both user has person contact linked to the company contact company_members = company_contact.members.all() assert get_person_contact(admin_user) in company_members assert get_person_contact(new_staff_user) in company_members
def _test_exception_delete_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) exception_name = "Exception %s" % index exception = AvailabilityException.objects.create( name=exception_name, start_datetime=now(), end_datetime=now()) exception.shops = [shop] extra_exception = AvailabilityException.objects.create( name="Extra Exception %s" % index, start_datetime=now(), end_datetime=now()) extra_exception.shops = [shop] assert AvailabilityException.objects.filter(name=exception_name).exists() view_func = AvailabilityExceptionDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request, pk=exception.pk) if hasattr(response, "render"): response.render() assert response.status_code == 302 assert not AvailabilityException.objects.filter(name=exception_name).exists() # Make sure that this staff can't remove other people discounts other_exceptions = AvailabilityException.objects.exclude(shops=shop) exception_count = other_exceptions.count() for coupon in other_exceptions: view_func = AvailabilityExceptionDeleteView.as_view() request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop) set_shop(request, shop) with pytest.raises(Http404): response = view_func(request, pk=coupon.pk) if hasattr(response, "render"): response.render() assert exception_count == AvailabilityException.objects.exclude(shops=shop).count()
def test_product_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() product = factories.get_default_product() shop_product = product.get_shop_instance(shop) shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition(browser, lambda x: x.is_text_present(shop_product.product.name)) # as this is added through javascript, add an extra timeout wait_until_condition(browser, lambda x: x.is_text_present("You are adding a product."), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ "a.shepherd-enabled[href='#basic-information-section']", "a.shepherd-enabled[href='#additional-details-section']", "a.shepherd-enabled[href='#manufacturer-section']", "a.shepherd-enabled[href*='-additional-section']", "a.shepherd-enabled[href='#product-media-section']", "a.shepherd-enabled[href='#product-images-section']", "a.shepherd-enabled[href='#contact-group-pricing-section']", "a.shepherd-enabled[href='#contact-group-discount-section']" ] # Scroll top before starting to click. For some reason the first # item is not found without this. For Firefox or Chrome the browser # does not do any extra scroll which could hide the first item. # Steps are scrollTo false on purpose since the scrollTo true is the # config which does not work in real world. browser.execute_script("window.scrollTo(0,0)") for target in category_targets: try: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css(".shepherd-button.btn-primary").last.click() except ElementNotInteractableException: move_to_element(browser, ".shepherd-button.btn-primary") wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "product", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition(browser, lambda x: not x.is_text_present("You are adding a product."), timeout=20) assert is_tour_complete(shop2, "product", user) is False browser.visit(live_server + "/logout") browser.visit(live_server + "/sa")
def test_delete_saved_card(rf, stripe_payment_processor): shop = factories.get_default_shop() user = factories.create_random_user() contact = get_person_contact(user) view = StripeSavedPaymentInfoView.as_view() delete_view = StripeDeleteSavedPaymentInfoView.as_view() # retrieve the saved card view request = apply_request_middleware(rf.get("/"), customer=contact, shop=shop, user=user) response = view(request) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Save your card details for a faster checkout. You can change or delete it at any time." in content def return_stripe_mock_data(*args, **kwargs): return StripeCustomerData(**CUSTOMER_MOCK_DATA) with mock.patch("stripe.Customer.retrieve", new=return_stripe_mock_data): with mock.patch("stripe.Customer.modify", new=return_stripe_mock_data): with mock.patch("stripe.Customer.create", new=return_stripe_mock_data): # attach payment details request = apply_request_middleware(rf.post("/", { "stripeToken": "xpto" }), customer=contact, shop=shop, user=user) response = view(request) assert response.status_code == 302 assert response.url.endswith(reverse("shuup:stripe_saved_payment")) # make sure there is stripe customer assert StripeCustomer.objects.filter(contact=contact, customer_token=CUSTOMER_MOCK_DATA["id"]).exists() def get_delete_mock(): mock_for_delete = mock.Mock(wraps=StripeCustomerData(**CUSTOMER_MOCK_DATA)) mock_for_delete.sources = mock.Mock() mock_for_delete.sources.retrieve = mock.Mock() return mock_for_delete with mock.patch("stripe.Customer.retrieve") as mocked: mock_for_delete = get_delete_mock() mocked.return_value = mock_for_delete # Delete the source request = apply_request_middleware(rf.post("/", { "source_id": CUSTOMER_MOCK_DATA["sources"]["data"][0]["id"] }), customer=contact, shop=shop, user=user) response = delete_view(request) mock_for_delete.sources.retrieve.delete.asset_called() # delete with error mock_for_delete = get_delete_mock() mock_for_delete.sources.retrieve.side_effect = stripe.StripeError("dummy") mocked.return_value = mock_for_delete response = delete_view(request) mock_for_delete.sources.retrieve.delete.asset_called()
def test_set_shop(rf, set_shop_fn, get_shop_fn): with override_settings(SHUUP_ENABLE_MULTIPLE_SHOPS=True): activate("en") factories.get_default_shop() shop1 = Shop.objects.create(identifier="shop1", status=ShopStatus.ENABLED) shop2 = Shop.objects.create(identifier="shop2", status=ShopStatus.ENABLED) normal_user = factories.create_random_user() staff_user = factories.create_random_user(is_staff=True) request = apply_request_middleware(rf.post("/"), user=normal_user, skip_session=True) # user not staff with pytest.raises(PermissionDenied) as exc: set_shop_fn(request, shop1) assert exc.value == "You must be a staff user" # staff user now with pytest.raises(PermissionDenied) as exc: request = apply_request_middleware(rf.post("/"), user=staff_user) assert exc.value == "You are not a staff member of this shop" # the user is not member of the shop staff with pytest.raises(PermissionDenied): set_shop_fn(request, shop1) assert get_shop_fn(request) is None # user is member of the shop staff shop1.staff_members.add(staff_user) request = apply_request_middleware(rf.post("/"), user=staff_user, skip_session=True) set_shop_fn(request, shop1) assert get_shop_fn(request) == shop1 # can't set a shop which user is not member with pytest.raises(PermissionDenied): set_shop_fn(request, shop2) assert get_shop_fn(request) == shop1 # adds the user to another shop shop2.staff_members.add(staff_user) set_shop_fn(request, shop2) assert get_shop_fn(request) == shop2
def test_coupon_with_supplier_filter(rf, admin_user): shop = get_default_shop() activate("en") view = MultiselectAjaxView.as_view() superuser1 = create_random_user(is_superuser=True, is_staff=True) supplier1 = Supplier.objects.create(identifier=superuser1.username) superuser2 = create_random_user(is_superuser=True, is_staff=True) supplier2 = Supplier.objects.create(identifier=superuser2.username) supplier_provider = "shuup.testing.supplier_provider.UsernameSupplierProvider" with override_settings(SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider): code = Coupon.objects.create(code="LEAFS", active=True, shop=shop, supplier=supplier1) results = _get_search_results(rf, view, "campaigns.Coupon", "LEAFS", superuser1) assert len(results) == 1 assert results[0].get("id") == code.id assert results[0].get("name") == code.code results = _get_search_results(rf, view, "campaigns.Coupon", "LEAFS", superuser2) assert len(results) == 0
def test_dashboard_item(rf): shop = factories.get_default_shop() user = factories.create_random_user() contact = get_person_contact(user) view = DashboardView.as_view() request = apply_request_middleware(rf.get("/"), customer=contact, shop=shop, user=user) response = view(request) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Saved Card" in content
def test_home_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: x.is_text_present("Hi, new shop owner!"), timeout=30) wait_until_condition(browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ ".shepherd-enabled[data-target-id='category-1'", ".shepherd-enabled[data-target-id='category-2'", ".shepherd-enabled[data-target-id='category-3'", ".shepherd-enabled[data-target-id='category-5'", ".shepherd-enabled[data-target-id='category-9'", ".shepherd-enabled[data-target-id='category-4'", ".shepherd-enabled[data-target-id='category-6'", ".shepherd-enabled[data-target-id='category-7'", ".shepherd-enabled[data-target-id='category-8'", ".shepherd-enabled#site-search", ".shepherd-enabled.shop-btn.visit-store", ] for target in category_targets: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: x.is_text_present("We're done!"), timeout=30) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "home", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/home") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") wait_until_condition(browser, lambda x: not x.is_text_present("Hi, new shop owner!")) assert is_tour_complete(shop2, "home", user) is False
def test_owner_can_see_invisible_page(rf): user = create_random_user() page = create_page(shop=get_default_shop(), available_from=None) view_func = PageView.as_view() request = apply_request_middleware(rf.get("/"), user=user) with pytest.raises(Http404): response = view_func(request, url=page.url) page.created_by = user page.save() response = view_func(request, url=page.url) response.render() assert "<h1>Bacon ipsum" in response.rendered_content
def test_edit_object_view_no_permissions(rf): user = factories.create_random_user("en", is_staff=True) shop = factories.get_default_shop() shop.staff_members.add(user) view = EditObjectView.as_view() product = factories.create_product("p1", shop, factories.get_default_supplier()) model = ".".join(ContentType.objects.get_for_model(product).natural_key()) # no permission with pytest.raises(Problem) as error: _get_edit_object_view(rf, view, model, product.id, user, shop) assert "You do not have the required permission" in str(error)
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("shuup:gdpr_customer_dashboard")) assert response.status_code == 200 assert "My Data" in response.content.decode("utf-8") response = client.post(reverse("shuup:gdpr_download_data")) assert response._headers["content-disposition"][0] == "Content-Disposition" assert response.status_code == 200 from shuup.tasks.models import Task, TaskType from shuup.gdpr.models import GDPR_ANONYMIZE_TASK_TYPE_IDENTIFIER response = client.post(reverse("shuup:gdpr_anonymize_account")) assert response.status_code == 302 assert response.url.endswith(reverse("shuup: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_campaign_list_for_suppliers(rf, admin_user): """ To make things little bit more simple let's use only english as a language. """ shop = get_default_shop() superuser1 = create_random_user(is_superuser=True, is_staff=True) supplier1 = Supplier.objects.create(identifier=superuser1.username) superuser2 = create_random_user(is_superuser=True, is_staff=True) supplier2 = Supplier.objects.create(identifier=superuser2.username) supplier_provider = "shuup.testing.supplier_provider.UsernameSupplierProvider" with override_settings(LANGUAGES=[("en", "en")]): with override_settings(SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider): campaign1 = BasketCampaign.objects.create(name="test campaign", active=True, shop=shop, supplier=supplier1) campaign2 = BasketCampaign.objects.create(name="test campaign2", active=True, shop=shop, supplier=supplier2) view = BasketCampaignListView() request = apply_request_middleware(rf.get("/"), user=superuser1, shop=shop) assert get_supplier(request) == supplier1 view.request = request assert campaign1 in view.get_queryset() assert campaign2 not in view.get_queryset() request = apply_request_middleware(rf.get("/"), user=superuser2, shop=shop) assert get_supplier(request) == supplier2 view.request = request assert campaign1 not in view.get_queryset() assert campaign2 in view.get_queryset() # And actual superuser not linked to any supplier can see all like he should request = apply_request_middleware(rf.get("/"), user=admin_user, shop=shop) assert get_supplier(request) is None view.request = request assert campaign1 in view.get_queryset() assert campaign2 in view.get_queryset()
def test_shop_products_with_supplier_filter(rf, admin_user): shop = get_default_shop() activate("en") view = MultiselectAjaxView.as_view() superuser1 = create_random_user(is_superuser=True, is_staff=True) supplier1 = Supplier.objects.create(identifier=superuser1.username) superuser2 = create_random_user(is_superuser=True, is_staff=True) supplier2 = Supplier.objects.create(identifier=superuser2.username) product_name_en = "ok" product = create_product("test1", shop=shop, supplier=supplier1, **{"name": product_name_en}) shop_product = product.get_shop_instance(shop) assert shop_product.suppliers.filter(pk=supplier1.pk).exists() supplier_provider = "shuup.testing.supplier_provider.UsernameSupplierProvider" with override_settings(SHUUP_ADMIN_SUPPLIER_PROVIDER_SPEC=supplier_provider): results = _get_search_results(rf, view, "shuup.ShopProduct", "ok", superuser1) assert len(results) == 1 assert results[0].get("id") == shop_product.id assert results[0].get("name") == product_name_en results = _get_search_results(rf, view, "shuup.ShopProduct", "ok", superuser2) assert len(results) == 0
def test_basket_with_custom_shop(rf): """ Set a different shop for basket """ with override_settings(**CORE_BASKET_SETTINGS): shop1 = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") user = factories.create_random_user() request = apply_request_middleware(rf.get("/"), user=user, shop=shop1) basket_class = cached_load("SHUUP_BASKET_CLASS_SPEC") basket = basket_class(request, "basket", shop=shop2) assert basket.shop == shop2 product_shop2 = factories.create_product("product_shop2", shop2, factories.get_default_supplier(), 10) line = basket.add_product(factories.get_default_supplier(), shop2, product_shop2, 1) assert line.shop == shop2
def test_admin_contact_edit(rf, admin_user): shop = get_default_shop() admin_contact = get_person_contact(admin_user) staff = create_random_user(is_staff=True) shop.staff_members.add(staff) view_func = ContactDetailView.as_view() # non superuser can't edit superuser's contacts with pytest.raises(Http404): request = apply_request_middleware(rf.get("/"), user=staff) response = view_func(request, pk=admin_contact.pk) # superuser can request = apply_request_middleware(rf.get("/"), user=admin_user) response = view_func(request, pk=admin_contact.pk) assert response.status_code == 200
def test_force_contact_views(rf): shop = factories.get_default_shop() user = factories.create_random_user(is_staff=True) shop.staff_members.add(user) person_contact = get_person_contact(user) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact # Force contact to anonymous contact _call_force_view(request, force_anonymous_contact) # Re-process middlewares so we check the force contact request = apply_request_middleware(rf.get("/"), user=user) assert request.customer.is_anonymous assert get_person_contact(user).is_anonymous assert_all_good_with_random_user() # Force contact to person contact _call_force_view(request, force_person_contact) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact assert get_person_contact(user) == person_contact assert_all_good_with_random_user() # Force contact to company contact. This also ensures # company contact for staff user if does not exists. _call_force_view(request, force_company_contact) request = apply_request_middleware(rf.get("/"), user=user) assert get_company_contact(user) == request.customer assert person_contact in request.customer.members.all() assert request.person == person_contact assert_all_good_with_random_user() # Finally force back to person contact. Now without # forcing the request would have company contact # since company contact for shop staff was created # while forcing company. _call_force_view(request, force_person_contact) request = apply_request_middleware(rf.get("/"), user=user) assert request.customer == person_contact assert get_person_contact(user) == person_contact assert get_company_contact(user) is None assert_all_good_with_random_user()
def test_order_creator_company_multishop(): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): company = create_random_company() shop = get_shop(identifier="random-shop", enabled=True) source = seed_source(create_random_user(), shop) source.customer = company source.add_line( type=OrderLineType.PRODUCT, product=get_default_product(), supplier=get_default_supplier(), quantity=1, base_unit_price=source.create_price(10), ) creator = OrderCreator() creator.create_order(source) company.refresh_from_db() assert shop in company.shops.all()
def test_dashbord_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) # test with admin_user 1 initialize_admin_browser_test(browser, live_server, settings, shop=shop, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) wait_until_condition(browser, lambda x: x.is_text_present("Quicklinks")) wait_until_condition(browser, lambda x: x.is_element_present_by_css("#menu-button")) wait_until_condition( browser, lambda x: x.is_text_present("This is the dashboard for your store."), timeout=30) wait_until_condition( browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") wait_until_condition( browser, lambda x: not x.is_element_present_by_css(".shepherd-button")) wait_until_condition( browser, lambda x: is_tour_complete(shop, "dashboard", admin_user)) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") # test with admin_user 2 initialize_admin_browser_test(browser, live_server, settings, shop=shop, tour_complete=False, username=admin_user_2.username) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) wait_until_condition(browser, lambda x: x.is_element_present_by_css("#menu-button")) wait_until_condition( browser, lambda x: x.is_text_present("This is the dashboard for your store."), timeout=30) wait_until_condition( browser, lambda x: x.is_element_present_by_css(".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") wait_until_condition( browser, lambda x: not x.is_element_present_by_css(".shepherd-button")) wait_until_condition( browser, lambda x: is_tour_complete(shop, "dashboard", admin_user_2)) # check whether the tour is shown again browser.visit(live_server + "/sa") wait_until_condition( browser, lambda x: not x.is_text_present( "This is the dashboard for your store.")) assert is_tour_complete(shop2, "dashboard", admin_user) is False assert is_tour_complete(shop2, "dashboard", admin_user_2) is False
def test_product_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() product = factories.get_default_product() shop_product = product.get_shop_instance(shop) shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition( browser, lambda x: x.is_text_present(shop_product.product.name)) # as this is added through javascript, add an extra timeout wait_until_condition( browser, lambda x: x.is_text_present("You are adding a product."), timeout=30) wait_until_condition( browser, lambda x: x.is_element_present_by_css( ".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ "a.shepherd-enabled[href='#basic-information-section']", "a.shepherd-enabled[href='#additional-details-section']", "a.shepherd-enabled[href='#manufacturer-section']", "a.shepherd-enabled[href*='-additional-section']", "a.shepherd-enabled[href='#product-media-section']", "a.shepherd-enabled[href='#product-images-section']", "a.shepherd-enabled[href='#contact-group-pricing-section']", "a.shepherd-enabled[href='#contact-group-discount-section']" ] # Scroll top before starting to click. For some reason the first # item is not found without this. For Firefox or Chrome the browser # does not do any extra scroll which could hide the first item. # Steps are scrollTo false on purpose since the scrollTo true is the # config which does not work in real world. browser.execute_script("window.scrollTo(0,0)") for target in category_targets: try: wait_until_condition( browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css( ".shepherd-button.btn-primary").last.click() except ElementNotInteractableException: move_to_element(browser, ".shepherd-button.btn-primary") wait_until_condition( browser, lambda x: x.is_element_present_by_css(target)) browser.find_by_css( ".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "product", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/products/%d/" % shop_product.pk) wait_until_condition( browser, lambda x: not x.is_text_present("You are adding a product."), timeout=20) assert is_tour_complete(shop2, "product", user) is False browser.visit(live_server + "/logout") browser.visit(live_server + "/sa")
def test_reviews_view(rf): shop = factories.get_default_shop() customer = factories.create_random_person("en") user = factories.create_random_user("en") user.set_password("user") user.save() customer.user = user customer.save() client = SmartClient() client.login(username=user.username, password="******") # no reviews in dashboard response = client.get(reverse("shuup:dashboard")) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "You haven't made any reviews yet" in content # create some reviews for customer [create_random_review_for_reviwer(shop, customer) for _ in range(15)] # create some orders to review [create_random_order_to_review(shop, customer) for order in range(3)] # reload dashboard response = client.get(reverse("shuup:dashboard")) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Last reviews" in content # show all reviews response, soup = client.response_and_soup(reverse("shuup:product_reviews")) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Products to Review" in content form_data = extract_form_fields(soup) for key in form_data.keys(): if key.endswith("comment"): form_data[key] = Faker().text(100) if key.endswith("rating"): form_data[key] = random.randint(1, 5) if key.endswith("would_recommend"): form_data[key] = random.choice([True, False]) # post reviews request = rf.post("/") request.person = request.customer = customer request.shop = shop response = client.post(reverse("shuup:product_reviews"), data=form_data) assert response.status_code == 302 response = client.get(reverse("shuup:product_reviews")) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert "Products to Review" not in content
def test_order_shipments(rf, admin_user): shop = get_default_shop() supplier1 = get_supplier(module_identifier="simple_supplier", identifier="1", name="supplier1") supplier1.shops.add(shop) supplier2 = get_supplier(module_identifier="simple_supplier", identifier="2", name="supplier1") supplier2.shops.add(shop) product1 = create_product("sku1", shop=shop, default_price=10) shop_product1 = product1.get_shop_instance(shop=shop) shop_product1.suppliers.set([supplier1]) product2 = create_product("sku3", shop=shop, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED) shop_product2 = product1.get_shop_instance(shop=shop) shop_product2.suppliers.set([supplier2]) product_quantities = { supplier1.pk: { product1.pk: 20 }, supplier2.pk: { product2.pk: 10 } } def get_quantity(supplier, product): return product_quantities[supplier.pk][product.pk] order = create_empty_order(shop=shop) order.full_clean() order.save() # Let's test the order shipment section for superuser request = apply_request_middleware(rf.get("/"), user=admin_user, shop=shop) # Add product 3 to order for supplier 2 add_product_to_order(order, supplier2, product2, get_quantity(supplier2, product2), 8) # Product is not shippable so order section should not be available assert not ShipmentSection.visible_for_object(order, request) # Add product 2 to order for supplier 1 add_product_to_order(order, supplier1, product1, get_quantity(supplier1, product1), 7) # Now we should see the shipment section assert ShipmentSection.visible_for_object(order, request) # Make order fully paid so we can start creting shipments and refunds order.cache_prices() order.check_all_verified() order.create_payment(order.taxful_total_price) assert order.is_paid() product_summary = order.get_product_summary() assert product_summary[product1.pk]["unshipped"] == 20 assert product_summary[product2.pk]["unshipped"] == 0 assert product_summary[product2.pk]["ordered"] == 10 # Fully ship the order order.create_shipment({product1: 5}, supplier=supplier1) order.create_shipment({product1: 5}, supplier=supplier1) order.create_shipment({product1: 10}, supplier=supplier1) assert not order.get_unshipped_products() assert not order.is_fully_shipped() context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 # One for each supplier assert len(context["delete_urls"].keys()) == 3 # One for each shipment # Let's create staff user without any permissions staff_user = create_random_user(is_staff=True) group = get_default_permission_group() staff_user.groups.add(group) shop.staff_members.add(staff_user) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 0 assert len(context["delete_urls"].keys()) == 0 assert len(context["set_sent_urls"].keys()) == 0 set_permissions_for_group(group, ["order.create-shipment"]) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 assert len(context["delete_urls"].keys()) == 0 assert len(context["set_sent_urls"].keys()) == 0 set_permissions_for_group(group, [ "order.create-shipment", "order.delete-shipment", "order.set-shipment-sent" ]) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 assert len(context["delete_urls"].keys()) == 3 assert len(context["set_sent_urls"].keys()) == 3 # works fine while rendering rendered_content = loader.render_to_string( ShipmentSection.template, context={ ShipmentSection.identifier: context, "order": order, }, ) all_urls = list(context["delete_urls"].values()) all_urls.extend(list(context["set_sent_urls"].values())) for url in all_urls: assert url in rendered_content assert order.get_sent_shipments().count() == 0 order.shipments.filter(status=ShipmentStatus.NOT_SENT) == 3 client = Client() client.force_login(admin_user) # mark all shipments as sent! for mark_sent_url in context["set_sent_urls"].values(): response = client.post(mark_sent_url) assert response.status_code == 302 order.refresh_from_db() assert order.is_fully_shipped() assert order.get_sent_shipments().count() == 3 order.shipments.filter(status=ShipmentStatus.NOT_SENT) == 0 # Make product1 unshipped product1.shipping_mode = ShippingMode.NOT_SHIPPED product1.save() # We still should see the order shipment section since existing shipments assert ShipmentSection.visible_for_object(order, request) # list all shipments in shipments list view response = client.get("{}?jq={}".format( reverse("shuup_admin:order.shipments.list"), json.dumps({ "perPage": 10, "page": 1 }))) assert response.status_code == 200 data = json.loads(response.content) assert len(data["items"]) == 3 for item in data["items"]: assert item["status"] == "Sent" # Let's delete all shipments since both products is unshipped and we # don't need those. for shipment in order.shipments.all(): shipment.soft_delete() assert not ShipmentSection.visible_for_object(order, request)
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_ajax_select_view_with_contacts_multipleshop(rf, contact_cls): shop1 = get_default_shop() shop2 = get_shop(identifier="shop2") staff = create_random_user(is_staff=True) shop1.staff_members.add(staff) shop2.staff_members.add(staff) view = MultiselectAjaxView.as_view() model_name = "shuup.%s" % contact_cls._meta.model_name customer = contact_cls.objects.create(name="Michael Jackson", email="*****@*****.**") customer_shop1 = contact_cls.objects.create(name="Roberto", email="*****@*****.**") customer_shop2 = contact_cls.objects.create(name="Maria", email="*****@*****.**") results = _get_search_results(rf, view, model_name, "michael", staff) assert len(results) == 0 customer.add_to_shop(shop1) customer.add_to_shop(shop2) customer_shop1.add_to_shop(shop1) customer_shop2.add_to_shop(shop2) for shop in [shop1, shop2]: results = _get_search_results(rf, view, model_name, "michael", staff, shop=shop) assert len(results) == 1 assert results[0].get("id") == customer.id assert results[0].get("name") == customer.name results = _get_search_results(rf, view, model_name, "roberto", staff, shop=shop) if shop == shop1: assert len(results) == 1 assert results[0].get("id") == customer_shop1.id assert results[0].get("name") == customer_shop1.name else: assert len(results) == 0 results = _get_search_results(rf, view, model_name, "maria", staff, shop=shop) if shop == shop2: assert len(results) == 1 assert results[0].get("id") == customer_shop2.id assert results[0].get("name") == customer_shop2.name else: assert len(results) == 0
def test_view_availability(admin_user, rf): supplier = get_default_supplier() shop_one = get_shop(True, "USD", enabled=True, identifier="one", name="Shop One") supplier.shops.add(shop_one) simone = create_random_user(username="******") simone.is_staff = True simone.save() shop_one.staff_members.add(simone) peter = create_random_user(username="******") peter.is_staff = True peter.save() shop_one.staff_members.add(peter) shop_two = get_shop(True, "USD", enabled=True, identifier="two", name="Shop Two") assert shop_one.pk != shop_two.pk supplier.shops.add(shop_two) calle = create_random_user(username="******") calle.is_staff = True calle.save() shop_two.staff_members.add(calle) product = create_product("simple-test-product", shop_one) order = create_order_with_product(product, supplier, 6, 6, shop=shop_one) # Simone and Peter should access to this order. Calle should get 404 def test_view(view, order, shop, user, data=None): if data: request = apply_request_middleware(rf.post("/", data), user=user, shop=shop) else: request = apply_request_middleware(rf.get("/"), user=user, shop=shop) response = view.as_view()(request, pk=order.pk) # Gets for view in [ OrderDetailView, OrderSetStatusView, OrderCreatePaymentView, OrderSetPaidView, OrderAddressEditView ]: test_view(view, order, shop_one, simone) test_view(view, order, shop_one, peter) with pytest.raises(Http404): test_view(view, order, shop_two, calle) test_view(NewLogEntryView, order, shop_one, simone, {"message": "message here"}) test_view(NewLogEntryView, order, shop_one, peter, {"message": "message here"}) with pytest.raises(Http404): test_view(NewLogEntryView, order, shop_two, calle, {"message": "message here"}) test_view(UpdateAdminCommentView, order, shop_one, simone, {"comment": "comment here"}) test_view(UpdateAdminCommentView, order, shop_one, peter, {"comment": "comment here"}) with pytest.raises(Http404): test_view(UpdateAdminCommentView, order, shop_two, calle, {"comment": "comment here"}) def test_shipment_view(order, shop, supplier, user): request = apply_request_middleware(rf.get("/"), user=user, shop=shop) response = OrderCreateShipmentView.as_view()(request, pk=order.pk, supplier_pk=supplier.pk) test_shipment_view(order, shop_one, supplier, simone) test_shipment_view(order, shop_one, supplier, peter) with pytest.raises(Http404): test_shipment_view(order, shop_two, supplier, calle) # Create shipment to test delete shipment view shipment = order.create_shipment_of_all_products(supplier) def test_shipment_delete_view(shipment, shop, user): request = apply_request_middleware(rf.post("/"), user=user, shop=shop) response = ShipmentDeleteView.as_view()(request, pk=shipment.pk, supplier_pk=supplier.pk) test_shipment_delete_view(shipment, shop_one, simone) test_shipment_delete_view(shipment, shop_one, peter) with pytest.raises(Http404): test_shipment_delete_view(shipment, shop_two, calle) # Create payment to test refund and delete payment view order.create_payment(order.taxful_total_price) payment = order.payments.first() assert payment is not None for view in [OrderCreateRefundView, OrderCreateFullRefundView]: test_view(view, order, shop_one, simone) test_view(view, order, shop_one, peter) with pytest.raises(Http404): test_view(view, order, shop_two, calle) def test_payment_delete_view(payment, shop, user): request = apply_request_middleware(rf.post("/"), user=user, shop=shop) response = OrderDeletePaymentView.as_view()(request, pk=payment.pk) test_payment_delete_view(payment, shop_one, simone) test_payment_delete_view(payment, shop_one, peter) with pytest.raises(Http404): test_payment_delete_view(payment, shop_two, calle)
def _create_random_staff(shop): user = factories.create_random_user(is_staff=True) shop.staff_members.add(user) return user
def test_page_form(rf, admin_user): with override_settings(LANGUAGES=[("en", "en")]): activate("en") shop = get_default_shop() gdpr_settings = GDPRSettings.get_for_shop(shop) gdpr_settings.enabled = True gdpr_settings.save() original_gdpr_page = ensure_gdpr_privacy_policy(shop) versions = Version.objects.get_for_object(original_gdpr_page) assert len(versions) == 1 # consent to this with user user = factories.create_random_user("en") assert not GDPRUserConsent.objects.filter(shop=shop, user=user).exists() original_consent = create_user_consent_for_all_documents(shop, user) assert GDPRUserConsent.objects.filter(shop=shop, user=user).count() == 1 # create one outside the usual flow GDPRUserConsent.objects.create(user=user, shop=shop) assert GDPRUserConsent.objects.filter(shop=shop, user=user).count() == 2 # consent again new_consent = create_user_consent_for_all_documents(shop, user) assert GDPRUserConsent.objects.filter(shop=shop, user=user).count() == 1 assert original_consent.pk == new_consent.pk version = versions[0] assert GDPRUserConsentDocument.objects.filter( page=original_gdpr_page, version=version).exists() assert is_documents_consent_in_sync(shop, user) assert Page.objects.count() == 1 view = PageEditView.as_view() # load the page request = apply_request_middleware(rf.get("/"), user=admin_user) response = view(request, pk=original_gdpr_page.pk) assert 200 <= response.status_code < 300 # update the page post_data = { "base-content__en": "test_data", "base-available_from": "", "base-url__en": "test", "base-title__en": "defa", "base-available_to": "", } request = apply_request_middleware(rf.post("/", post_data), user=admin_user) response = view(request, pk=original_gdpr_page.pk) if hasattr(response, "render"): content = response.render() assert response.status_code in [200, 302] versions = Version.objects.get_for_object(original_gdpr_page) assert len(versions) == 4 # saved 4 times in total assert not is_documents_consent_in_sync(shop, user) create_user_consent_for_all_documents(shop, user) assert is_documents_consent_in_sync(shop, user)
"id": object_id or "" } if mode: data["mode"] = mode request = apply_request_middleware(rf.get(reverse("shuup_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 urls = [] try:
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_consent_required(rf): activate("en") shop = factories.get_default_shop() user = factories.create_random_user() page = ensure_gdpr_privacy_policy(shop) assert page gdpr_settings = GDPRSettings.get_for_shop(shop) assert not gdpr_settings.enabled assert gdpr_settings.privacy_policy_page == page assert not should_reconsent_privacy_policy(shop, user) assert is_documents_consent_in_sync(shop, user) # settings not enabled assert page in get_possible_consent_pages(shop) # enable gpdr gdpr_settings.enabled = True gdpr_settings.save() assert gdpr_settings.privacy_policy_page == get_privacy_policy_page(shop) assert not is_documents_consent_in_sync(shop, user) # create revisioned page hidden_page = Page.objects.create(shop=shop, available_from=None) assert hidden_page not in Page.objects.visible(shop=shop) assert gdpr_settings.privacy_policy_page == get_privacy_policy_page(shop) assert hidden_page in get_possible_consent_pages(shop) with reversion.create_revision(): page.save() create_user_consent_for_all_documents(shop, user) assert GDPRUserConsent.objects.filter(user=user, shop=shop).count() == 1 consent = GDPRUserConsent.objects.get(user=user, shop=shop) pages = [c.page for c in consent.documents.all()] assert page in pages assert hidden_page not in pages # not there due not visible with reversion.create_revision(): page.save() # add a new (visible) page available_page = Page.objects.create(shop=shop, available_from=now()) assert available_page in Page.objects.visible(shop=shop) create_user_consent_for_all_documents(shop, user) consent = GDPRUserConsent.objects.get(user=user, shop=shop) pages = [c.page for c in consent.documents.all()] assert page in pages assert hidden_page not in pages # not there due not visible assert available_page not in pages # not there due defined in settings assert available_page in get_possible_consent_pages(shop) assert available_page not in get_active_consent_pages(shop) gdpr_settings.consent_pages.add(available_page) gdpr_settings.refresh_from_db() assert gdpr_settings.privacy_policy_page assert gdpr_settings.consent_pages.count() == 1 assert available_page in get_active_consent_pages(shop) assert consent.documents.count() == 1 create_user_consent_for_all_documents(shop, user) consent = GDPRUserConsent.objects.get(user=user, shop=shop) assert consent.documents.count() == 2 assert is_documents_consent_in_sync(shop, user) pages = [c.page for c in consent.documents.all()] assert page in pages assert hidden_page not in pages # not there due not visible assert available_page in pages
def test_reorder_view(): shop = factories.get_default_shop() factories.get_default_shipping_method() factories.get_default_payment_method() supplier1 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop) supplier2 = factories.get_supplier(SimpleSupplierModule.identifier, shop=shop) assert supplier1.pk != supplier2.pk product_supplier1 = factories.create_product( "product_supplier1", shop=shop, supplier=supplier1, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED) product_supplier2 = factories.create_product( "product_supplier2", shop=shop, supplier=supplier2, default_price=20, shipping_mode=ShippingMode.NOT_SHIPPED) user = factories.create_random_user("en") user.set_password("user") user.save() customer = factories.create_random_person("en") customer.user = user customer.save() order = factories.create_random_order( customer=customer, shop=shop, products=[product_supplier1, product_supplier2], completion_probability=0, random_products=False) suppliers = [line.supplier for line in order.lines.products()] assert supplier1 in suppliers assert supplier2 in suppliers client = Client() client.login(username=user.username, password="******") # list orders response = client.get(reverse("shuup:personal-orders")) assert response.status_code == 200 content = response.content.decode("utf-8") assert "<td>%d</td>" % order.id in content assert "<td>Received</td>" in content # go to order detail response = client.get(reverse("shuup:show-order", kwargs=dict(pk=order.pk))) assert response.status_code == 200 content = response.content.decode("utf-8") assert "Add all products to cart" in content reorder_url = reverse("shuup:reorder-order", kwargs=dict(pk=order.pk)) assert reorder_url in content # reorder products response = client.get(reorder_url) assert response.status_code == 302 assert response.url.endswith(reverse("shuup:basket")) # go to basket response = client.get(response.url) assert response.status_code == 200 content = response.content.decode("utf-8") # ensure the basket contain those products and suppliers basket_key = client.session["basket_basket_key"]["key"] from shuup.front.models import StoredBasket basket = StoredBasket.objects.get(key=basket_key) lines = basket.data["lines"] product_supplier = [(line["product_id"], line["supplier_id"]) for line in lines] assert (product_supplier1.pk, supplier1.pk) in product_supplier assert (product_supplier2.pk, supplier2.pk) in product_supplier assert product_supplier1.name in content assert product_supplier2.name in content assert "You are unable to proceed to checkout!" not in content
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("shuup: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("shuup: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("shuup: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 assert_all_good_with_random_user(): assert not get_person_contact(factories.create_random_user()).is_anonymous
def test_bump_caches_signal(rf): """ Test that caches are actually bumped also when calling bump function with id's """ initial_price = 10 shop1 = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2", domain="shop2") now = datetime(2018, 1, 1, 9, 0, tzinfo=pytz.UTC) # 01/01/2018 09:00 AM def assert_cache_bumped(prods): for sp in prods: key, val = context_cache.get_cached_value( identifier="is_orderable", item=sp, context={"customer": contact}, supplier=factories.get_default_supplier(), stock_managed=bool( factories.get_default_supplier() and factories.get_default_supplier().stock_managed), quantity=1, allow_cache=True, ) assert val is None with patch("django.utils.timezone.now", new=lambda: now): product1 = factories.create_product( "product", shop=shop1, supplier=factories.get_default_supplier(), default_price=initial_price) product2 = factories.create_product( "product2", shop=shop2, supplier=factories.get_default_supplier(), default_price=20) user = factories.create_random_user() contact = get_person_contact(user) shop_product1 = product1.shop_products.filter(shop=shop1).first() shop_product2 = product2.shop_products.filter(shop=shop2).first() assert shop_product1.is_orderable( factories.get_default_supplier(shop1), contact, 1) is True assert shop_product2.is_orderable( factories.get_default_supplier(shop2), contact, 1) is True # Test single product id bumping context_cache.bump_cache_for_product(product2.id, shop=shop2) context_cache.bump_cache_for_product(product1.id, shop=shop1) assert_cache_bumped([shop_product1, shop_product2]) # Test list bumping context_cache.bump_cache_for_product([product2.id], shop=shop2) context_cache.bump_cache_for_product([product1.id], shop=shop1) assert_cache_bumped([shop_product1, shop_product2])
def test_home_tour(browser, admin_user, live_server, settings): shop = factories.get_default_shop() shop2 = factories.get_shop(identifier="shop2") admin_user_2 = factories.create_random_user(is_staff=True, is_superuser=True) admin_user_2.set_password("password") admin_user_2.save() shop.staff_members.add(admin_user) shop.staff_members.add(admin_user_2) for user in [admin_user, admin_user_2]: initialize_admin_browser_test(browser, live_server, settings, username=user.username, tour_complete=False) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) browser.visit(live_server + "/sa/home") wait_until_condition( browser, lambda x: x.is_text_present("Hi, new shop owner!"), timeout=30) wait_until_condition( browser, lambda x: x.is_element_present_by_css( ".shepherd-button.btn-primary")) click_element(browser, ".shepherd-button.btn-primary") category_targets = [ ".shepherd-enabled[data-target-id='category-1'", ".shepherd-enabled[data-target-id='category-2'", ".shepherd-enabled[data-target-id='category-3'", ".shepherd-enabled[data-target-id='category-5'", ".shepherd-enabled[data-target-id='category-9'", ".shepherd-enabled[data-target-id='category-4'", ".shepherd-enabled[data-target-id='category-6'", ".shepherd-enabled[data-target-id='category-7'", ".shepherd-enabled[data-target-id='category-8'", ".shepherd-enabled#site-search", ".shepherd-enabled.shop-btn.visit-store", ] for target in category_targets: wait_until_condition(browser, lambda x: x.is_element_present_by_css(target)) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: x.is_text_present("We're done!"), timeout=30) move_to_element(browser, ".shepherd-button.btn-primary") browser.find_by_css(".shepherd-button.btn-primary").last.click() wait_until_condition(browser, lambda x: is_tour_complete(shop, "home", user)) # check whether the tour is shown again browser.visit(live_server + "/sa/home") wait_until_condition( browser, lambda x: not x.is_text_present("Hi, new shop owner!")) browser.visit(live_server + "/logout") browser.visit(live_server + "/sa") wait_until_condition( browser, lambda x: not x.is_text_present("Hi, new shop owner!")) assert is_tour_complete(shop2, "home", user) is False
def test_api_token(): """ Test whether the API returns the access token correctly """ shop = factories.get_default_shop() user = factories.create_random_user() password = "******" user.set_password(password) user.save() group = Group.objects.create(name="group 1") client = APIClient() api_access = create_random_api_access() # try logging without the api access credentials response = client.post("/api/auth/", format="json", data={ "username": user.username, "password": password }) assert response.status_code == status.HTTP_400_BAD_REQUEST response = client.post("/api/auth/", format="json", data={ "username": user.username, "password": password, "api_key": api_access.key, "api_secret": api_access.secret }) assert response.status_code == status.HTTP_200_OK jwt = response.data["token"] client.credentials(HTTP_AUTHORIZATION="JWT " + jwt) # add permission for the user group scope = get_view_role(FrontUserViewSet, get_role_for("get", "retrieve")) permission_groups = APIPermissionGroups.objects.create( name="special group") permission_groups.groups.add(group) permission_groups.permissions.add( APIPermissionScope.objects.get_or_create(identifier=scope)[0]) user.groups.add(group) api_access.permissions_groups.add(permission_groups) # refresh the token to include the new permission response = client.post("/api/auth/refresh/", format="json", data={"token": jwt}) assert response.status_code == status.HTTP_200_OK jwt = response.data["token"] client.credentials(HTTP_AUTHORIZATION="JWT " + jwt) # fetch user data response = client.get("/api/shuup/front/user/me/", format="json") assert response.status_code == status.HTTP_200_OK assert response.data["id"] == user.id # verify token client.credentials(HTTP_AUTHORIZATION="") response = client.post("/api/auth/verify/", format="json", data={"token": jwt}) assert response.status_code == status.HTTP_200_OK # disable the key api_access.enabled = False api_access.save() client.credentials(HTTP_AUTHORIZATION="JWT " + jwt) response = client.get("/api/shuup/front/user/me/", format="json") assert response.status_code == status.HTTP_403_FORBIDDEN
def test_contact_list_multiple_shop(rf, admin_user): shop1 = get_default_shop() shop2 = get_shop(identifier="shop2", name="Shop 2") staff = create_random_user(is_staff=True) Contact.objects.all().delete() shop1.staff_members.add(staff) shop2.staff_members.add(staff) contact1 = create_random_person(locale="en_US") contact1.shops.add(shop1) contact2 = create_random_person(locale="en_US") contact2.shops.add(shop2) contact3 = create_random_company(shop1) contact3.shops.add(shop1) superuser_contact = get_person_contact(admin_user) view_func = ContactListView.as_view() # do not send which shop.. it should return all contacts, except superuser contacts payload = {"jq": json.dumps({"perPage": 100, "page": 1})} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk in contacts assert contact2.pk in contacts assert contact3.pk in contacts assert superuser_contact.pk not in contacts # request contacts from shop1 payload = {"jq": json.dumps({"perPage": 100, "page": 1}), "shop": shop1.pk} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk in contacts assert contact2.pk not in contacts assert contact3.pk in contacts assert superuser_contact.pk not in contacts # request contacts from shop2 payload = {"jq": json.dumps({"perPage": 100, "page": 1}), "shop": shop2.pk} request = apply_request_middleware(rf.get("/", data=payload), user=staff) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk not in contacts assert contact2.pk in contacts assert contact3.pk not in contacts assert superuser_contact.pk not in contacts # list all contacts when using a superuser payload = {"jq": json.dumps({"perPage": 100, "page": 1})} request = apply_request_middleware(rf.get("/", data=payload), user=admin_user) response = view_func(request) assert response.status_code == 200 data = json.loads(response.content.decode("utf-8")) contacts = [contact["_id"] for contact in data["items"]] assert contact1.pk in contacts assert contact2.pk in contacts assert contact3.pk in contacts assert superuser_contact.pk in contacts
def test_order_shipment_section(rf, admin_user): shop = get_default_shop() supplier1 = Supplier.objects.create(identifier="1", name="supplier1") supplier1.shops.add(shop) supplier2 = Supplier.objects.create(identifier="2") supplier2.shops.add(shop) product1 = create_product("sku1", shop=shop, default_price=10) shop_product1 = product1.get_shop_instance(shop=shop) shop_product1.suppliers.set([supplier1]) product2 = create_product("sku3", shop=shop, default_price=10, shipping_mode=ShippingMode.NOT_SHIPPED) shop_product2 = product1.get_shop_instance(shop=shop) shop_product2.suppliers.set([supplier2]) product_quantities = { supplier1.pk: { product1.pk: 20 }, supplier2.pk: { product2.pk: 10 } } def get_quantity(supplier, product): return product_quantities[supplier.pk][product.pk] order = create_empty_order(shop=shop) order.full_clean() order.save() # Let's test the order shipment section for superuser request = apply_request_middleware(rf.get("/"), user=admin_user, shop=shop) # Add product 3 to order for supplier 2 add_product_to_order(order, supplier2, product2, get_quantity(supplier2, product2), 8) # Product is not shippable so order section should not be available assert not ShipmentSection.visible_for_object(order, request) # Add product 2 to order for supplier 1 add_product_to_order(order, supplier1, product1, get_quantity(supplier1, product1), 7) # Now we should see the shipment section assert ShipmentSection.visible_for_object(order, request) # Make order fully paid so we can start creting shipments and refunds order.cache_prices() order.check_all_verified() order.create_payment(order.taxful_total_price) assert order.is_paid() product_summary = order.get_product_summary() assert product_summary[product1.pk]["unshipped"] == 20 assert product_summary[product2.pk]["unshipped"] == 0 assert product_summary[product2.pk]["ordered"] == 10 # Fully ship the order order.create_shipment({product1: 5}, supplier=supplier1) order.create_shipment({product1: 5}, supplier=supplier1) order.create_shipment({product1: 10}, supplier=supplier1) assert not order.get_unshipped_products() assert order.is_fully_shipped() context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 # One for each supplier assert len(context["delete_urls"].keys()) == 3 # One for each shipment # Let's create staff user without any permissions staff_user = create_random_user(is_staff=True) group = get_default_permission_group() staff_user.groups.add(group) shop.staff_members.add(staff_user) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 0 assert len(context["delete_urls"].keys()) == 0 set_permissions_for_group(group, ["order.create-shipment"]) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 assert len(context["delete_urls"].keys()) == 0 set_permissions_for_group( group, ["order.create-shipment", "order.delete-shipment"]) request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop) context = ShipmentSection.get_context_data(order, request) assert len(context["suppliers"]) == 2 assert len(context["create_urls"].keys()) == 2 assert len(context["delete_urls"].keys()) == 3 # Make product1 unshipped product1.shipping_mode = ShippingMode.NOT_SHIPPED product1.save() # We still should see the order shipment section since existing shipments assert ShipmentSection.visible_for_object(order, request) # Let's delete all shipments since both products is unshipped and we # don't need those. for shipment in order.shipments.all(): shipment.soft_delete() assert not ShipmentSection.visible_for_object(order, request)
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))
def test_user_selector(admin_user): shop = get_default_shop() u = create_random_user() assert get_object_selector_results(User, shop, admin_user, u.first_name)
def _test_discount_list_view(rf, index): shop = factories.get_shop(identifier="shop%s" % index, enabled=True) staff_user = factories.create_random_user(is_staff=True) shop.staff_members.add(staff_user) discount1 = Discount.objects.create( identifier="discount_without_effects_%s" % index, shop=shop) discount2 = Discount.objects.create( shop=shop, identifier="discount_with_amount_value_only_%s" % index, discount_amount_value=20, start_datetime=now(), end_datetime=now() + datetime.timedelta(days=2), ) discount3 = Discount.objects.create( shop=shop, identifier="discount_with_amount_and_discounted_price_%s" % index, discount_amount_value=20, discounted_price_value=4, start_datetime=now(), end_datetime=now() + datetime.timedelta(days=2), ) discount4 = Discount.objects.create( shop=shop, identifier="test_with_discounted_price_and_percentage_%s" % index, discounted_price_value=4, discount_percentage=0.20, start_datetime=now(), end_datetime=now() + datetime.timedelta(days=2), ) view_func = DiscountListView.as_view() request = apply_request_middleware(rf.get( "/", {"jq": json.dumps({ "perPage": 100, "page": 1 })}), user=staff_user, shop=shop) set_shop(request, shop) response = view_func(request) if hasattr(response, "render"): response.render() assert response.status_code == 200 view_instance = DiscountListView() view_instance.request = request assert request.shop == shop assert view_instance.get_queryset().count() == 4 data = json.loads(view_instance.get(request).content.decode("UTF-8")) assert len(data["items"]) == 4 discount1_data = [ item for item in data["items"] if item["_id"] == discount1.pk ][0] assert discount1_data["discount_effect"] == "-" discount2_data = [ item for item in data["items"] if item["_id"] == discount2.pk ][0] assert len(discount2_data["discount_effect"].split(",")) == 1 assert "20" in discount2_data["discount_effect"] discount3_data = [ item for item in data["items"] if item["_id"] == discount3.pk ][0] assert len(discount3_data["discount_effect"].split(",")) == 2 assert "20" in discount3_data["discount_effect"] assert "4" in discount3_data["discount_effect"] discount4_data = [ item for item in data["items"] if item["_id"] == discount4.pk ][0] assert len(discount4_data["discount_effect"].split(",")) == 2 assert "20" in discount4_data["discount_effect"] assert "4" in discount4_data["discount_effect"]
def test_contact_company_edit_multishop(rf): with override_settings(SHUUP_MANAGE_CONTACTS_PER_SHOP=True, SHUUP_ENABLE_MULTIPLE_SHOPS=True): staff_user = create_random_user(is_staff=True) shop1 = get_shop(identifier="shop-1", enabled=True) shop2 = get_shop(identifier="shop-2", enabled=True) shop1.staff_members.add(staff_user) shop2.staff_members.add(staff_user) # only available in shop2 contact = create_random_person(locale="en_US", minimum_name_comp_len=5, shop=shop2) # only available in shop1 company = create_random_company(shop1) view = ContactEditView.as_view() # permission denied for contact and shop1 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) with pytest.raises(Http404): response = view(request, pk=contact.id) # permission granted for contact and shop2 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) response = view(request, pk=contact.id) assert response.status_code == 200 # permission denied for company and shop2 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop2) with pytest.raises(Http404): response = view(request, pk=company.id) # permission granted for company and shop1 request = apply_request_middleware(rf.get("/"), user=staff_user, shop=shop1) response = view(request, pk=company.id) assert response.status_code == 200 # contact belongs to shop 1 assert not contact.registered_in(shop1) assert not contact.in_shop(shop1) assert contact.registered_in(shop2) assert contact.in_shop(shop2) # company belongs to shop 2 assert not company.registered_in(shop2) assert not company.in_shop(shop2) assert company.registered_in(shop1) assert company.in_shop(shop1) # save contact under shop 1 request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop1) contact_base_form = PersonContactBaseForm( request=request, instance=contact, data={ "first_name": "test first name", "last_name": contact.last_name, "gender": contact.gender.value }, ) assert contact_base_form.is_valid(), contact_base_form.errors contact_base_form.save() contact.refresh_from_db() assert contact.registered_in(shop2) assert not contact.registered_in(shop1) assert contact.in_shop(shop1) assert contact.in_shop(shop2) # save company under shop 2 request = apply_request_middleware(rf.post("/"), user=staff_user, shop=shop2) form = CompanyContactBaseForm( request=request, instance=company, data={ "name": "eww", }, ) assert form.is_valid(), form.errors form.save() company.refresh_from_db() assert company.registered_in(shop1) assert not company.registered_in(shop2) assert company.in_shop(shop1) assert company.in_shop(shop2)
def test_edit_button_no_permission(browser, admin_user, live_server, settings): shop = get_default_shop() manager_group = Group.objects.create(name="Managers") manager = create_random_user("en", is_staff=True) manager.username = "******" manager.set_password("password") manager.save() manager.groups.add(manager_group) shop.staff_members.add(manager) # add permissions for Product admin module manager_permissions = set(["dashboard", "Products", "shop_product.new"]) set_permissions_for_group(manager_group, manager_permissions) get_default_product_type() get_default_sales_unit() get_default_tax_class() initialize_admin_browser_test(browser, live_server, settings, username=manager.username) url = reverse("shuup_admin:shop_product.new") browser.visit("%s%s" % (live_server, url)) sku = "testsku" name = "Some product name" price_value = 10 short_description = "short but gold" browser.fill("base-sku", sku) browser.fill("base-name__en", name) browser.fill("base-short_description__en", short_description) browser.fill("shop%s-default_price_value" % shop.pk, price_value) wait_until_appeared(browser, "#id_shop%d-primary_category ~ .quick-add-btn a.btn" % shop.id) click_element(browser, "#id_shop%d-primary_category ~ .quick-add-btn a.btn" % shop.id) wait_until_appeared(browser, "#create-object-iframe") # no permission to add category with browser.get_iframe('create-object-iframe') as iframe: error = "Can't view this page. You do not have the required permissions: category.new" wait_until_condition(iframe, condition=lambda x: x.is_text_present(error)) # close iframe click_element(browser, "#create-object-overlay a.close-btn") # add permission to add category manager_permissions.add("category.new") manager_permissions.add("category.edit") set_permissions_for_group(manager_group, manager_permissions) # click to add category again click_element(browser, "#id_shop%d-primary_category ~ .quick-add-btn a.btn" % shop.id) wait_until_appeared(browser, "#create-object-iframe") # add the category with browser.get_iframe('create-object-iframe') as iframe: assert Category.objects.count() == 0 wait_until_appeared(iframe, "input[name='base-name__en']") iframe.fill("base-name__en", "Test Category") time.sleep(3) # Let's just wait here to the iFrame to open fully (for Chrome and headless) wait_until_appeared(iframe, "button[form='category_form']") click_element(browser, "button[form='category_form']") wait_until_condition(browser, condition=lambda x: Category.objects.count() == 1, timeout=20) assert Category.objects.first().name == "Test Category" # remove the edit category permissions # add permission to add category manager_permissions.remove("category.edit") set_permissions_for_group(manager_group, manager_permissions) # click to edit the button click_element(browser, "#id_shop%d-primary_category ~ .edit-object-btn a.btn" % shop.id) # no permission to edit category with browser.get_iframe('create-object-iframe') as iframe: error = "Can't view this page. You do not have the required permission(s): `category.edit`." wait_until_condition(iframe, condition=lambda x: x.is_text_present(error)) # close iframe click_element(browser, "#create-object-overlay a.close-btn") manager_permissions.add("category.edit") set_permissions_for_group(manager_group, manager_permissions) click_element(browser, "#id_shop%d-primary_category ~ .edit-object-btn a.btn" % shop.id) wait_until_appeared(browser, "#create-object-iframe") new_cat_name = "Changed Name" with browser.get_iframe('create-object-iframe') as iframe: wait_until_appeared(iframe, "input[name='base-name__en']") iframe.fill("base-name__en", new_cat_name) time.sleep(3) # Let's just wait here to the iFrame to open fully (for Chrome and headless) wait_until_appeared(iframe, "button[form='category_form']") click_element(browser, "button[form='category_form']") wait_until_condition(browser, condition=lambda x: Category.objects.first().name == new_cat_name, timeout=20)
def test_reset_admin_user_password_errors(client): get_default_shop() user = factories.create_random_user("en", is_staff=True, is_active=False, email=REGULAR_USER_EMAIL) user.set_password(REGULAR_USER_PASSWORD) user.save() assert len(mail.outbox) == 0 # user not active response = client.post(reverse("shuup_admin:request_password"), data={"email": user.email}) assert response.status_code == 302 assert len(mail.outbox) == 0 user.is_active = True user.is_staff = False user.save() # user not staff response = client.post(reverse("shuup_admin:request_password"), data={"email": user.email}) assert response.status_code == 302 assert len(mail.outbox) == 0 # non-existent email response = client.post(reverse("shuup_admin:request_password"), data={"email": "*****@*****.**"}) assert response.status_code == 302 assert len(mail.outbox) == 0 user.is_staff = True user.save() # all set response = client.post(reverse("shuup_admin:request_password"), data={"email": user.email}) assert response.status_code == 302 assert len(mail.outbox) == 1 email_content = mail.outbox[0].body url = email_content[email_content.find("http"):] _, _, _, _, _, uid, token, _ = url.split("/") # invalid token new_password = "******" response = client.post(reverse("shuup_admin:recover_password", kwargs=dict(uidb64=uid, token="invalid")), data={ "new_password1": new_password, "new_password2": new_password }) assert response.status_code == 400 assert "This recovery link is invalid" in response.content.decode("utf-8") # invalid uid response = client.post(reverse("shuup_admin:recover_password", kwargs=dict(uidb64="uid", token=token)), data={ "new_password1": new_password, "new_password2": new_password }) assert response.status_code == 400 assert "This recovery link is invalid" in response.content.decode("utf-8") # invalid passwords response = client.post(reverse("shuup_admin:recover_password", kwargs=dict(uidb64=uid, token=token)), data={ "new_password1": new_password, "new_password2": "wrong" }) assert response.status_code == 200 # Django forms likes to return invalid forms as 200. So be it. assert escape("The two password fields didn't match." ) in response.content.decode("utf-8") # all good response = client.post(reverse("shuup_admin:recover_password", kwargs=dict(uidb64=uid, token=token)), data={ "new_password1": new_password, "new_password2": new_password }) assert response.status_code == 302
def test_variation_activation(rf): shop = get_default_shop() parent = create_product(printable_gibberish(), shop=shop) user = create_random_user(is_superuser=True, is_staff=True) request = apply_request_middleware(rf.get("/"), user=user, shop=shop) form = VariationVariablesDataForm(parent_product=parent, request=request) assert len(ProductVariationVariable.objects.all() ) == 0 # Assert no active Variations are present assert form.get_variation_templates() == [ ] # Assert no templates exist (yet) var_data_dict = { 'data': json.dumps({"variable_values": var_data}), 'template_name': '' } # Base skeleton form.cleaned_data = var_data_dict form.is_valid() form.save() assert len( ProductVariationVariable.objects.filter(product=parent)) == 1 # Size assert len(ProductVariationVariableValue.objects.all()) == 2 # X,S var = ProductVariationVariable.objects.first() val_1 = ProductVariationVariableValue.objects.first() val_2 = ProductVariationVariableValue.objects.last() var_data_one_value = [{ "pk": "%s" % var.pk, "identifier": "", "names": { "en": "Size" }, "values": [{ "pk": "%s" % val_1.pk, "identifier": "", "texts": { "en": "X" } }, { "pk": "%s" % val_2.pk, "DELETE": True }] }] # Delete one value var_data_dict['data'] = json.dumps({"variable_values": var_data_one_value}) form.cleaned_data = var_data_dict form.save() assert len(ProductVariationVariable.objects.filter(product=parent)) == 1 assert len(ProductVariationVariableValue.objects.all()) == 1 var_data_dict["template_name"] = printable_gibberish() # Create template form.save() assert len(ProductVariationVariable.objects.filter(product=parent)) == 1 assert len(ProductVariationVariableValue.objects.all()) == 1 assert len(form.get_variation_templates()) == 1 template_identifier = form.get_variation_templates()[0].get('identifier') # dict with template identifier which contains only one ProductVariationVariableValue data two_values_dict = json.dumps({ "variable_values": var_data, 'template_identifier': template_identifier }) # Has two PVVV var_data_dict['data'] = two_values_dict var_data_dict['template_name'] = '' form.cleaned_data = var_data_dict form.save() assert len(ProductVariationVariable.objects.filter(product=parent)) == 1 assert len(ProductVariationVariableValue.objects.all()) == 2