def add_product_image(product): media1 = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True) media2 = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True) product.primary_image = media1 product.media.add(media2) product.save()
def add_product_image(product): media1 = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True) media2 = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True) product.primary_image = media1 product.media.add(media2) product.save()
def test_admin_form_part(admin_user): factories.get_default_shop() client = SmartClient() client.login(username=admin_user.username, password="******") assert Page.objects.count() == 0 response, soup = client.response_and_soup( reverse("shuup_admin:simple_cms.page.new")) assert response.status_code == 200 payload = extract_form_fields(soup) # do some cleaning for key in payload.keys(): if payload[key] is None: payload[key] = "" # create 9 articles for i in range(9): payload.update({ "base-title__en": "My Article %d" % i, "base-url__en": "my-article-%d" % i, "base-available_from": "0%s/01/2018 00:00:00" % (i + 1), "base-available_to": "0%s/01/2019 00:00:00" % (i + 1), "base-content__en": "Some content here %d" % i, "base-template_name": "shuup_cms_blog/blog_page.jinja", "blog-is_blog_article": True, "blog-image": factories.get_random_filer_image().pk, "blog-small_description__en": "small description %d" % i }) response = client.post(reverse("shuup_admin:simple_cms.page.new"), data=payload) assert response.status_code == 302 assert Page.objects.count() == (i + 1) response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs=dict(url=payload["base-url__en"]))) assert response.status_code == 200 assert soup.find("div", {"class": "article-features"}) # update blog image of the last page payload.update({ "blog-image": factories.get_random_filer_image().pk, }) response = client.post(reverse("shuup_admin:simple_cms.page.edit", kwargs=dict(pk=Page.objects.last().pk)), data=payload) assert response.status_code == 302
def test_send_product_media_image(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) image = get_random_filer_image() with open(image.path, "rb") as f: img_base64 = base64.b64encode(f.read()).decode() uri = "data:image/jpeg;base64,{}".format(img_base64) media_data = { "translations": {"en": {"title": "My image title", "description": "My image description"}}, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri, "path": "/what/the/folder", } response = client.post( "/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data) ) assert response.status_code == status.HTTP_201_CREATED assert product.media.count() == 1 product_media = product.media.first() assert product_media.title == media_data["translations"]["en"]["title"] assert product_media.description == media_data["translations"]["en"]["description"] assert product_media.shops.count() == len(media_data["shops"]) assert set(product_media.shops.all().values_list("pk", flat=True)) >= set(media_data["shops"]) assert product_media.kind.value == media_data["kind"] assert product_media.file.folder.pretty_logical_path == media_data["path"] with open(product_media.file.path, "rb") as f: assert img_base64 == base64.b64encode(f.read()).decode()
def test_summernote_editor_picture(browser, admin_user, live_server, settings): activate("en") factories.get_default_shop() factories.get_default_product_type() factories.get_default_sales_unit() factories.get_default_tax_class() filer_image = factories.get_random_filer_image() initialize_admin_browser_test(browser, live_server, settings) browser.driver.set_window_size(1920, 1080) url = reverse("shuup_admin:shop_product.new") browser.visit("%s%s" % (live_server, url)) wait_until_condition(browser, condition=lambda x: x.is_text_present("New shop product")) img_icon_selector = "#id_base-description__en-editor-wrap i[class='note-icon-picture']" move_to_element(browser, img_icon_selector) click_element(browser, img_icon_selector) wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] # make sure the image was added to the editor wait_until_appeared( browser, "#id_base-description__en-editor-wrap .note-editable img[src='%s']" % filer_image.url, timeout=20 )
def test_carousel_create(browser, admin_user, live_server, settings): shop = factories.get_default_shop() filer_image = factories.get_random_filer_image() factories.get_default_category() initialize_admin_browser_test(browser, live_server, settings, shop=shop) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) assert not Carousel.objects.exists() browser.visit(live_server + "/sa/carousels/new") wait_until_condition(browser, lambda x: x.is_text_present("New Carousel")) browser.fill("base-name", "Carrot") click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']") assert Carousel.objects.count() == 1 carousel = Carousel.objects.first() browser.visit(live_server + "/sa/carousels/%d/" % carousel.pk) time.sleep(1) wait_until_condition(browser, lambda x: x.is_text_present(carousel.name)) click_element(browser, "a[href='#slides-section']") wait_until_appeared(browser, ".slide-add-new-panel") # add 1 slide click_element(browser, ".slide-add-new-panel") wait_until_condition(browser, lambda x: x.is_text_present("Slide 1")) wait_until_appeared(browser, "a[href='#collapse1']") click_element(browser, "a[href='#collapse1']") browser.find_by_css( "#slide_1-en [name='slides-__slide_prefix__-caption__en']").fill( "New Slide") click_element(browser, "[name='slides-__slide_prefix__-category_link'] + .select2") wait_until_appeared( browser, ".select2-container #select2-id_slides-__slide_prefix__-category_link-results li" ) click_element( browser, ".select2-container #select2-id_slides-__slide_prefix__-category_link-results li:last-child" ) browser.find_by_css("#slide_1-en [data-dropzone='true']").click() wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] wait_until_appeared(browser, ".dz-image img[alt='%s']" % filer_image.name) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']")
def test_saved_articles(rf): shop = factories.get_default_shop() articles = [] # create 3 blog pages for i in range(10): article = Page.objects.create( shop=shop, title="Article %d" % i, url="blog-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content %d" % i, template_name="shuup_cms_blog/blog_page.jinja") BlogArticle.objects.create(page=article, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description %d" % i) articles.append(article) user = factories.create_random_user() user.set_password("pass") contact = get_person_contact(user) assert not contact.options request = apply_request_middleware(rf.get("/"), user=user) # save article #1 response = AddSavedArticlesView.as_view()(request, pk=articles[0].pk) assert response.status_code == 302 contact.refresh_from_db() options = json.loads(contact.options) if isinstance( contact.options, str) else contact.options assert options["saved_articles"] == [articles[0].pk] # save article #3 response = AddSavedArticlesView.as_view()(request, pk=articles[2].pk) assert response.status_code == 302 contact.refresh_from_db() options = json.loads(contact.options) if isinstance( contact.options, str) else contact.options assert options["saved_articles"] == [articles[0].pk, articles[2].pk] # list saved articles response = SavedArticlesView.as_view()(request) assert response.status_code == 200 response.render() content = response.content.decode("utf-8") assert 'data-article="%d"' % articles[0].pk in content assert 'data-article="%d"' % articles[2].pk in content # removed saved article #3 response = RemoveSavedArticlesView.as_view()(request, pk=articles[2].pk) assert response.status_code == 302 contact.refresh_from_db() options = json.loads(contact.options) if isinstance( contact.options, str) else contact.options assert options["saved_articles"] == [articles[0].pk]
def create_images_for_product(shop, product): medias = [] for _ in range(3): product_media = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE) product_media.file = factories.get_random_filer_image() product_media.save() product_media.shops.add(shop) medias.append(product_media) return medias
def test_thumbnail_cache(): image1 = factories.get_random_filer_image() image2 = factories.get_random_filer_image() media = ProductMedia.objects.create(product=factories.get_default_product(), file=image2) cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(image1) cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and cached_url == url cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(media) cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and cached_url == url img_url = "http://www.shuup.com/logo.png" cache_key, cached_url = _get_cached_thumbnail_url(img_url, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(img_url) cache_key, cached_url = _get_cached_thumbnail_url(img_url, alias=None, generate=True) assert cache_key and cached_url == url source = Thumbnailer(file=BytesIO(TEST_PNG), name="logo.png") source.url = "/media/logo.png" cache_key, cached_url = _get_cached_thumbnail_url(source, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(source) cache_key, cached_url = _get_cached_thumbnail_url(source, alias=None, generate=True) assert cache_key and cached_url == url # check whether caches are bumped image1.save() cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and not cached_url media.save() cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and not cached_url media.delete() image1.delete() image2.delete()
def test_thumbnail_cache(): image1 = factories.get_random_filer_image() image2 = factories.get_random_filer_image() media = ProductMedia.objects.create(product=factories.get_default_product(), file=image2) cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(image1) cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and cached_url == url cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(media) cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and cached_url == url img_url = "http://www.shuup.com/logo.png" cache_key, cached_url = _get_cached_thumbnail_url(img_url, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(img_url) cache_key, cached_url = _get_cached_thumbnail_url(img_url, alias=None, generate=True) assert cache_key and cached_url == url source = Thumbnailer(file=BytesIO(TEST_PNG), name="logo.png") source.url = '/media/logo.png' cache_key, cached_url = _get_cached_thumbnail_url(source, alias=None, generate=True) assert cache_key and not cached_url url = thumbnail(source) cache_key, cached_url = _get_cached_thumbnail_url(source, alias=None, generate=True) assert cache_key and cached_url == url # check whether caches are bumped image1.save() cache_key, cached_url = _get_cached_thumbnail_url(image1, alias=None, generate=True) assert cache_key and not cached_url media.save() cache_key, cached_url = _get_cached_thumbnail_url(media, alias=None, generate=True) assert cache_key and not cached_url media.delete() image1.delete() image2.delete()
def test_products_all_shops(admin_user): shop1 = get_default_shop() shop1.logo = get_random_filer_image() shop1.save() person1 = create_random_person() person1.user = admin_user person1.save() shop2 = Shop.objects.create() shop2.favicon = get_random_filer_image() shop2.save() supplier1 = create_simple_supplier("supplier1") supplier2 = create_simple_supplier("supplier2") # create 2 products for shop2 product1 = create_product("product1", shop=shop1, supplier=supplier1) product2 = create_product("product2", shop=shop2, supplier=supplier2) product3 = create_product("product3", shop=shop2, supplier=supplier1) # list all orderable products - 2 just created are for shop2 request = get_request("/api/shuup/front/shop_products/", admin_user, person1) response = FrontShopProductViewSet.as_view({"get": "list"})(request) response.render() products = json.loads(response.content.decode("utf-8")) assert len(products) == 3 assert products[0]["product_id"] == product1.id assert products[0]["shop"]["id"] == shop1.id assert products[0]["shop"]["logo"] == request.build_absolute_uri( shop1.logo.url) assert products[1]["product_id"] == product2.id assert products[1]["shop"]["id"] == shop2.id assert products[1]["shop"]["favicon"] == request.build_absolute_uri( shop2.favicon.url) assert products[2]["product_id"] == product3.id assert products[2]["shop"]["id"] == shop2.id assert products[2]["shop"]["favicon"] == request.build_absolute_uri( shop2.favicon.url)
def add_product_image(product, purchased=False): media1 = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True, purchased=purchased, ) media2 = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=get_random_filer_image(), enabled=True, public=True, purchased=purchased, ) product.primary_image = media1 product.media.add(media2) product.save() return (media1, media2)
def create_categories(shop): Category.objects.create( name="Category 1", status=CategoryStatus.VISIBLE, image=factories.get_random_filer_image()) category2 = Category.objects.create( name="Category 2", description="parent", slug="cat-2", status=CategoryStatus.VISIBLE) Category.objects.create( name="Category 2.1", description="visible", slug="cat-2-1", status=CategoryStatus.VISIBLE, parent=category2) Category.objects.create( name="Category 2.2", description="invisible", slug="cat-2-2", status=CategoryStatus.INVISIBLE, parent=category2) for category in Category.objects.all(): category.shops.add(shop)
def test_products_all_shops(admin_user): shop1 = get_default_shop() shop1.logo = get_random_filer_image() shop1.save() person1 = create_random_person() person1.user = admin_user person1.save() shop2 = Shop.objects.create(status=ShopStatus.ENABLED) shop2.favicon = get_random_filer_image() shop2.save() supplier1 = create_simple_supplier("supplier1") supplier2 = create_simple_supplier("supplier2") # create 2 products for shop2 product1 = create_product("product1", shop=shop1, supplier=supplier1) product2 = create_product("product2", shop=shop2, supplier=supplier2) product3 = create_product("product3", shop=shop2, supplier=supplier1) # list all orderable products - 2 just created are for shop2 request = get_request("/api/shuup/front/shop_products/", admin_user, person1) response = FrontShopProductViewSet.as_view({"get": "list"})(request) response.render() products = json.loads(response.content.decode("utf-8")) assert len(products) == 3 assert products[0]["product_id"] == product1.id assert products[0]["shop"]["id"] == shop1.id assert products[0]["shop"]["logo"] == request.build_absolute_uri(shop1.logo.url) assert products[1]["product_id"] == product2.id assert products[1]["shop"]["id"] == shop2.id assert products[1]["shop"]["favicon"] == request.build_absolute_uri(shop2.favicon.url) assert products[2]["product_id"] == product3.id assert products[2]["shop"]["id"] == shop2.id assert products[2]["shop"]["favicon"] == request.build_absolute_uri(shop2.favicon.url)
def test_send_product_media_erros(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) media_data = { "translations": { "en": { "title": "My image title", "description": "My image description" } }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value } # do not set file or external_url response = client.post("/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "You may set either `file` or `external_url`." in response_data[ "non_field_errors"] # do not set path for file image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) media_data = { "translations": { "en": { "title": "My image title", "description": "My image description" } }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri } response = client.post("/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "`path` is required when `file` is set." in response_data[ "non_field_errors"]
def test_carousel_create(browser, admin_user, live_server, settings): shop = factories.get_default_shop() filer_image = factories.get_random_filer_image() factories.get_default_category() initialize_admin_browser_test(browser, live_server, settings, shop=shop) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) assert not Carousel.objects.exists() browser.visit(live_server + "/sa/carousels/new") wait_until_condition(browser, lambda x: x.is_text_present("New Carousel")) browser.fill("base-name", "Carrot") click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']") assert Carousel.objects.count() == 1 carousel = Carousel.objects.first() browser.visit(live_server + "/sa/carousels/%d/" % carousel.pk) wait_until_condition(browser, lambda x: x.is_text_present(carousel.name)) click_element(browser, "a[href='#slides-section']") wait_until_appeared(browser, ".slide-add-new-panel") # add 1 slide click_element(browser, ".slide-add-new-panel") wait_until_condition(browser, lambda x: x.is_text_present("Slide 1")) wait_until_appeared(browser, "a[href='#collapse1']") click_element(browser, "a[href='#collapse1']") browser.find_by_css("#slide_1-en [name='slides-__slide_prefix__-caption__en']").fill("New Slide") click_element(browser, "[name='slides-__slide_prefix__-category_link'] + .select2") wait_until_appeared(browser, ".select2-container #select2-id_slides-__slide_prefix__-category_link-results li") click_element(browser, ".select2-container #select2-id_slides-__slide_prefix__-category_link-results li:last-child") browser.find_by_css("#slide_1-en [data-dropzone='true']").click() wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] wait_until_appeared(browser, ".dz-image img[alt='%s']" % filer_image.name) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']")
def test_product_copy(rf, admin_user): factories.get_default_attribute_set() shop = factories.get_default_shop() supplier = factories.get_default_supplier() request = apply_request_middleware(rf.get("/", {}), user=admin_user) price = 10 product = factories.create_product("product", shop=shop, supplier=supplier, default_price=price) attribute_key = "author" attribute_value = "batman" product.set_attribute_value(attribute_key, attribute_value) media = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=factories.get_random_filer_image(), enabled=True, public=True) product.primary_image = media product.media.add(media) product.save() category = factories.get_default_category() shop_product = product.get_shop_instance(shop) shop_product.primary_category = category shop_product.save() shop_product.categories.set([category]) assert Product.objects.count() == 1 view_func = ProductCopyView.as_view() response = view_func(request, pk=shop_product.pk) if hasattr(response, "render"): response.render() assert Product.objects.count() == 2 new_product = Product.objects.first() new_shop_product = new_product.get_shop_instance(shop) assert new_product assert new_product.pk != product.pk assert new_product.name == product.name assert new_shop_product assert new_shop_product.suppliers.first() == shop_product.suppliers.first() assert new_shop_product.categories.first( ) == shop_product.categories.first() assert new_product.media.first().file.pk == product.media.first().file.pk assert new_product.get_attribute_value(attribute_key) == attribute_value
def get_product(sku, shop): product = Product.objects.filter(sku=sku).first() if not product: product = create_product(sku) image = get_random_filer_image() media = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=image, enabled=True, public=True) product.primary_image = media product.save() assert product.primary_image_id sp = ShopProduct.objects.create( product=product, shop=shop, visibility=ShopProductVisibility.ALWAYS_VISIBLE ) sp.suppliers.add(get_default_supplier()) return product
def get_product(sku, shop): product = Product.objects.filter(sku=sku).first() if not product: product = create_product(sku) image = get_random_filer_image() media = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, file=image, enabled=True, public=True) product.primary_image = media product.save() assert product.primary_image_id sp = ShopProduct.objects.create( product=product, shop=shop, visibility=ShopProductVisibility.ALWAYS_VISIBLE ) sp.suppliers.add(get_default_supplier()) return product
def test_send_product_media_erros(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) media_data = { "translations": { "en": {"title": "My image title", "description": "My image description"} }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value } # do not set file or external_url response = client.post("/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "You may set either `file` or `external_url`." in response_data["non_field_errors"] # do not set path for file image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) media_data = { "translations": { "en": {"title": "My image title", "description": "My image description"} }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri } response = client.post("/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST response_data = json.loads(response.content.decode("utf-8")) assert "`path` is required when `file` is set." in response_data["non_field_errors"]
def test_summernote_editor_picture(browser, admin_user, live_server, settings): activate("en") factories.get_default_shop() factories.get_default_product_type() factories.get_default_sales_unit() factories.get_default_tax_class() filer_image = factories.get_random_filer_image() configuration.set(None, "shuup_product_tour_complete", True) initialize_admin_browser_test(browser, live_server, settings) browser.driver.set_window_size(1920, 1080) url = reverse("shuup_admin:shop_product.new") browser.visit("%s%s" % (live_server, url)) wait_until_appeared( browser, "#id_base-description__en-editor-wrap button[aria-label='Picture']") click_element( browser, "#id_base-description__en-editor-wrap button[aria-label='Picture']") wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] # make sure the image was added to the editor wait_until_appeared( browser, "#id_base-description__en-editor-wrap .note-editable img[src='%s']" % filer_image.url, timeout=20)
def test_send_product_media_image(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(f.read()).decode() uri = "data:image/jpeg;base64,{}".format(img_base64) media_data = { "translations": { "en": { "title": "My image title", "description": "My image description" } }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri, "path": "/what/the/folder" } response = client.post("/api/shuup/product/%d/add_media/" % product.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_201_CREATED assert product.media.count() == 1 product_media = product.media.first() assert product_media.title == media_data["translations"]["en"]["title"] assert product_media.description == media_data["translations"]["en"]["description"] assert product_media.shops.count() == len(media_data["shops"]) assert set(product_media.shops.all().values_list("pk", flat=True)) >= set(media_data["shops"]) assert product_media.kind.value == media_data["kind"] assert product_media.file.folder.pretty_logical_path == media_data["path"] with open(product_media.file.path, 'rb') as f: assert img_base64 == base64.b64encode(f.read()).decode()
def test_opengrah_admin(admin_user): shop = factories.get_default_shop() client = SmartClient() client.login(username=admin_user.username, password="******") assert Page.objects.count() == 0 response, soup = client.response_and_soup( reverse("shuup_admin:simple_cms.page.new")) assert response.status_code == 200 # save simple page payload = { "base-title__en": "My Article", "base-url__en": "my-article", "base-available_from": "01/01/2018 00:00:00", "base-available_to": "01/01/2019 00:00:00", "base-content__en": "Some content here", } response = client.post(reverse("shuup_admin:simple_cms.page.new"), data=payload) assert response.status_code == 302 assert Page.objects.count() == 1 page = Page.objects.first() # check the rendered page in front page_url = reverse("shuup:cms_page", kwargs=dict(url=page.url)) response, soup = client.response_and_soup(page_url) assert response.status_code == 200 assert soup.find("meta", attrs={ "property": "og:site_name", "content": shop.public_name }) assert soup.find("meta", attrs={"property": "og:url"}) assert soup.find("meta", attrs={ "property": "og:title", "content": page.title }) assert soup.find("meta", attrs={ "property": "og:type", "content": "website" }) assert soup.find("meta", attrs={ "property": "og:description", "content": page.content }) # set some open graph info random_image = factories.get_random_filer_image() payload.update({ "opengraph-title__en": "OG Title", "opengraph-tags__en": "OG Tags", "opengraph-section__en": "OG Section", "opengraph-description__en": "OG DESC", "opengraph-article_author__en": "OG AuthorName", "opengraph-og_type": PageOpenGraphType.Article.value, "opengraph-image": random_image.pk, }) response = client.post(reverse("shuup_admin:simple_cms.page.edit", kwargs=dict(pk=page.pk)), data=payload) assert response.status_code == 302 assert Page.objects.count() == 1 page = Page.objects.first() str(page.open_graph) # just for coverage assert page.open_graph.title == payload["opengraph-title__en"] assert page.open_graph.tags == payload["opengraph-tags__en"] assert page.open_graph.section == payload["opengraph-section__en"] assert page.open_graph.description == payload["opengraph-description__en"] assert page.open_graph.og_type.value == payload["opengraph-og_type"] assert page.open_graph.article_author == payload[ "opengraph-article_author__en"] # check the rendered page in front page_url = reverse("shuup:cms_page", kwargs=dict(url=page.url)) response, soup = client.response_and_soup(page_url) assert response.status_code == 200 assert soup.find("meta", attrs={ "property": "og:title", "content": payload["opengraph-title__en"] }) assert soup.find("meta", attrs={ "property": "og:type", "content": payload["opengraph-og_type"] }) assert soup.find("meta", attrs={ "property": "og:description", "content": payload["opengraph-description__en"] }) assert soup.find("meta", attrs={ "property": "og:type", "content": payload["opengraph-og_type"] }) assert soup.find("meta", attrs={ "property": "article:tag", "content": payload["opengraph-tags__en"] }) assert soup.find("meta", attrs={ "property": "article:section", "content": payload["opengraph-section__en"] }) assert soup.find("meta", attrs={ "property": "article:author", "content": payload["opengraph-article_author__en"] }) assert soup.find("meta", attrs={ "property": "article:modified_time", "content": page.modified_on.isoformat() }) assert soup.find("meta", attrs={ "property": "article:published_time", "content": page.available_from.isoformat() }) assert soup.find("meta", attrs={ "property": "article:expiration_time", "content": page.available_to.isoformat() }) img_node = soup.find("meta", attrs={"property": "og:image"}) assert img_node.attrs["content"].endswith(random_image.url)
def test_plugin(): shop = factories.get_default_shop() set_current_theme(ClassicGrayTheme.identifier, shop) blog_one_page = Page.objects.create( shop=shop, title="Blog One", url="blog_one", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") blog_two_page = Page.objects.create( shop=shop, title="Blog Two", url="blog_two", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") # create 10 blog pages for page in [blog_one_page, blog_two_page]: for i in range(10): article = Page.objects.create( shop=shop, title="Article %d %s" % (i, page.title), url="blog-%d-%s" % (i, page.url), available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content %d" % i, template_name="shuup_cms_blog/blog_page.jinja", parent=page) BlogArticle.objects.create( page=article, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description %d" % i) # create 3 non blog post pages for i in range(3): article = Page.objects.create( shop=shop, title="Nothing %d" % i, url="non-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="content %i" % i) theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) placeholder_name = "cms_page" context_one = {"page": blog_one_page} context_two = {"page": blog_two_page} layout_one = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context_one) layout_two = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context_two) assert isinstance(layout_one, PageLayout) assert isinstance(layout_two, PageLayout) assert layout_one.get_help_text({}) == "" assert layout_two.get_help_text({}) == "" assert blog_one_page.title in layout_two.get_help_text(context_one) assert blog_two_page.title in layout_two.get_help_text(context_two) serialized_one = layout_one.serialize() serialized_two = layout_two.serialize() assert len(serialized_one["rows"]) == 0 assert len(serialized_two["rows"]) == 0 assert serialized_one["name"] == placeholder_name assert serialized_two["name"] == placeholder_name layout_one.begin_column({"sm": 12}) layout_two.begin_column({"sm": 12}) layout_one.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {"blog_page": blog_one_page.pk}) layout_two.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {"blog_page": blog_two_page.pk}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_one, context_one), layout_one) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_two, context_two), layout_two) view_config.publish() client = SmartClient() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_one_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10 response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10 article_one = Page.objects.create( shop=shop, title="Article test", url="blog-test", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content test", template_name= "shuup_cms_blog/blog_page.jinja", # Add an article without a parent ) BlogArticle.objects.create(page=article_one, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description test") article_two = Page.objects.create( shop=shop, title="Article test 2", url="blog-test-2", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content test 2", template_name= "shuup_cms_blog/blog_page.jinja", # Add an article without a parent ) BlogArticle.objects.create(page=article_two, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description test 2") view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) # No blog page set means that only articles with no parent will be shown layout_two.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout_two, context_two), layout_two) view_config.publish() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 2 response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": article_one.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 1 assert soup.find("div", { "class": "article-title" }).text == article_two.title article_one.soft_delete() # Delete the article that has no parent article_two.soft_delete() # Delete the article that has no parent response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_two_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 0 article_with_parent = Page.objects.filter(parent=blog_one_page).first() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": article_with_parent.url})) assert response.status_code == 200 assert len(soup.find_all( "a", {"class": "article-card"})) == 9 # Assert there are 9 articles shown article_card_titles = soup.find_all("div", {"class": "article-title"}) article_card_titles = [title.text for title in article_card_titles] # Assert that the current visited article (article_with_parent) is not visible in Related articles assert article_with_parent.title not in article_card_titles
def test_manufacturer_api(admin_user): get_default_shop() client = APIClient() client.force_authenticate(user=admin_user) image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) manufacturer_data = { "name": "manu 1", "url": "http://www.google.com", "logo_path" : "/this/not/needed", "logo" : uri } response = client.post("/api/shuup/manufacturer/", content_type="application/json", data=json.dumps(manufacturer_data)) assert response.status_code == status.HTTP_201_CREATED manufacturer = Manufacturer.objects.first() assert manufacturer.name == manufacturer_data["name"] assert manufacturer.url == manufacturer_data["url"] assert manufacturer.logo.folder.pretty_logical_path == manufacturer_data["logo_path"] with open(manufacturer.logo.path, 'rb') as f: assert img_base64 == base64.b64encode(f.read()).decode() manufacturer_data.pop("logo_path") # Test error when not sending a path response = client.post("/api/shuup/manufacturer/", content_type="application/json", data=json.dumps(manufacturer_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert data["non_field_errors"][0] == "Path is required when sending a manufacturer logo." manufacturer_data["logo_path"] = "/second/path" # Testing second manufacturer manufacturer_data["name"] = "name 2" manufacturer_data["url"] = "http://yahoo.com" response = client.put("/api/shuup/manufacturer/%d/" % manufacturer.id, content_type="application/json", data=json.dumps(manufacturer_data)) assert response.status_code == status.HTTP_200_OK manufacturer = Manufacturer.objects.first() assert manufacturer.name == manufacturer_data["name"] assert manufacturer.url == manufacturer_data["url"] response = client.get("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert manufacturer.name == data["name"] assert manufacturer.url == data["url"] response = client.get("/api/shuup/manufacturer/") assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert manufacturer.name == data[0]["name"] assert manufacturer.url == data[0]["url"] response = client.delete("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_204_NO_CONTENT assert Manufacturer.objects.count() == 0 # create a product and relate it to a manufacturer product = create_product("product with manufacturer") manufacturer = Manufacturer.objects.create() product.manufacturer = manufacturer product.save() # shouldn't be possible to delete a manufacturer with a related product response = client.delete("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_400_BAD_REQUEST assert "This object can not be deleted because it is referenced by" in response.content.decode("utf-8") assert Manufacturer.objects.count() == 1
def test_product_media_api(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) # create 2 images for product, 1 with contents, other with external url image = get_random_filer_image() media = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=image, enabled=True, public=True) media_external = ProductMedia.objects.create( product=product, kind=ProductMediaKind.IMAGE, external_url="http://www.myimage.com/img.gif", enabled=True, public=True) product.primary_image = media product.save() # get product media response = client.get("/api/shuup/product_media/%d/" % media.pk) media_data = json.loads(response.content.decode("utf-8")) assert media_data["kind"] == media.kind.value assert media_data["product"] == product.pk assert media_data["public"] == media.public assert media_data["id"] == media.pk # get external media response = client.get("/api/shuup/product_media/%d/" % media_external.pk) media_data = json.loads(response.content.decode("utf-8")) assert media_data["kind"] == media_external.kind.value assert media_data["product"] == product.pk assert media_data["public"] == media_external.public assert media_data["id"] == media_external.pk assert media_data["external_url"] == media_external.external_url # update product media image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) media_data = { "translations": { "en": { "title": "title 2", "description": "desc2" } }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri, "path": "/what/the/zzzz" } response = client.put("/api/shuup/product_media/%d/" % media.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_200_OK media.refresh_from_db() assert media.title == media_data["translations"]["en"]["title"] assert media.description == media_data["translations"]["en"]["description"] assert media.shops.count() == len(media_data["shops"]) assert set(media.shops.all().values_list("pk", flat=True)) >= set( media_data["shops"]) assert media.kind.value == media_data["kind"] assert media.file.folder.pretty_logical_path == media_data["path"] with open(media.file.path, 'rb') as f: assert img_base64 == base64.b64encode(f.read()).decode() media_count = product.media.count() # deletes an image response = client.delete("/api/shuup/product_media/%d/" % media.pk) assert response.status_code == status.HTTP_204_NO_CONTENT assert media_count - 1 == product.media.count()
def test_manufacturer_api(admin_user): shop = get_default_shop() client = APIClient() client.force_authenticate(user=admin_user) image = get_random_filer_image() with open(image.path, "rb") as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) manufacturer_data = { "name": "manu 1", "url": "http://www.google.com", "logo_path": "/this/not/needed", "logo": uri } response = client.post("/api/shuup/manufacturer/", content_type="application/json", data=json.dumps(manufacturer_data)) assert response.status_code == status.HTTP_201_CREATED manufacturer = Manufacturer.objects.first() assert manufacturer.name == manufacturer_data["name"] assert manufacturer.url == manufacturer_data["url"] assert manufacturer.logo.folder.pretty_logical_path == manufacturer_data[ "logo_path"] with open(manufacturer.logo.path, "rb") as f: assert img_base64 == base64.b64encode(f.read()).decode() manufacturer_data.pop("logo_path") # Test error when not sending a path response = client.post("/api/shuup/manufacturer/", content_type="application/json", data=json.dumps(manufacturer_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert data["non_field_errors"][ 0] == "Path is required when sending a manufacturer logo." manufacturer_data[ "logo_path"] = "/second/path" # Testing second manufacturer manufacturer_data["name"] = "name 2" manufacturer_data["url"] = "http://yahoo.com" response = client.put( "/api/shuup/manufacturer/%d/" % manufacturer.id, content_type="application/json", data=json.dumps(manufacturer_data), ) assert response.status_code == status.HTTP_200_OK manufacturer = Manufacturer.objects.first() assert manufacturer.name == manufacturer_data["name"] assert manufacturer.url == manufacturer_data["url"] response = client.get("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert manufacturer.name == data["name"] assert manufacturer.url == data["url"] response = client.get("/api/shuup/manufacturer/") assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert manufacturer.name == data[0]["name"] assert manufacturer.url == data[0]["url"] response = client.delete("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_204_NO_CONTENT assert Manufacturer.objects.count() == 0 # create a product and relate it to a manufacturer product = create_product("product with manufacturer", shop=shop) manufacturer = Manufacturer.objects.create() product.manufacturer = manufacturer product.save() # shouldn't be possible to delete a manufacturer with a related product response = client.delete("/api/shuup/manufacturer/%d/" % manufacturer.id) assert response.status_code == status.HTTP_204_NO_CONTENT assert Manufacturer.objects.count() == 0 product.refresh_from_db() assert product.manufacturer is None
def test_carousel_multi_slide(browser, admin_user, live_server, settings): shop = factories.get_default_shop() filer_image = factories.get_random_filer_image() initialize_admin_browser_test(browser, live_server, settings, shop=shop) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) assert not Carousel.objects.exists() browser.visit(live_server + "/sa/carousels/new") wait_until_condition(browser, lambda x: x.is_text_present("New Carousel")) browser.fill("base-name", "Carrot") click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']") assert Carousel.objects.count() == 1 carousel = Carousel.objects.first() browser.visit(live_server + "/sa/carousels/%d/" % carousel.pk) wait_until_condition(browser, lambda x: x.is_text_present(carousel.name)) click_element(browser, "a[href='#slides-section']") wait_until_appeared(browser, ".slide-add-new-panel") # add 4 slides click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") wait_until_condition(browser, lambda x: x.is_text_present("Slide 3")) # delete slide3 wait_until_appeared(browser, "a[href='#collapse3']") click_element(browser, "a[href='#collapse3']") wait_until_appeared(browser, "#collapse3 .btn-remove-slide") click_element(browser, "#collapse3 .btn-remove-slide") wait_until_condition(browser, lambda x: not x.is_text_present("Slide 3")) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "a[href='#slides-section'].errors") click_element(browser, "a[href='#slides-section']") for slide_id in [0, 1, 2]: wait_until_appeared(browser, "a[href='#collapse%d']" % (slide_id + 1)) click_element(browser, "a[href='#collapse%d']" % (slide_id + 1)) browser.find_by_css("[name='slides-%d-caption__en']" % slide_id).fill("Slide") click_element(browser, "[name='slides-%d-category_link'] + .select2" % slide_id) wait_until_appeared(browser, ".select2-container #select2-id_slides-%d-category_link-results li" % slide_id) click_element(browser, ".select2-container #select2-id_slides-%d-category_link-results li:last-child" % slide_id) browser.find_by_css("#id_slides-%d-image__en-dropzone" % slide_id).click() wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] wait_until_appeared(browser, ".dz-image img[alt='%s']" % filer_image.name) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']")
def test_plugin(): shop = factories.get_default_shop() set_current_theme(ClassicGrayTheme.identifier, shop) blog_page = Page.objects.create(shop=shop, title="Blog", url="blog", available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="") # create 10 blog pages for i in range(10): article = Page.objects.create( shop=shop, title="Article %d" % i, url="blog-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="Content %d" % i, template_name="shuup_cms_blog/blog_page.jinja") BlogArticle.objects.create(page=article, is_blog_article=True, image=factories.get_random_filer_image(), small_description="description %d" % i) # create 3 non blog post pages for i in range(3): article = Page.objects.create( shop=shop, title="Nothing %d" % i, url="non-%d" % i, available_from=(now() - timedelta(days=10)), available_to=(now() + timedelta(days=10)), content="content %i" % i) theme = get_current_theme(shop) view_config = ViewConfig(theme=theme, shop=shop, view_name="PageView", draft=True) placeholder_name = "cms_page" context = {"page": blog_page} layout = view_config.get_placeholder_layout(PageLayout, placeholder_name, context=context) assert isinstance(layout, PageLayout) assert layout.get_help_text({}) == "" assert blog_page.title in layout.get_help_text(context) serialized = layout.serialize() assert len(serialized["rows"]) == 0 assert serialized["name"] == placeholder_name layout.begin_column({"sm": 12}) layout.add_plugin(ShuupCMSBlogArticleListPlugin.identifier, {}) view_config.save_placeholder_layout( get_layout_data_key(placeholder_name, layout, context), layout) view_config.publish() client = SmartClient() response, soup = client.response_and_soup( reverse("shuup:cms_page", kwargs={"url": blog_page.url})) assert response.status_code == 200 assert len(soup.find_all("a", {"class": "article-card"})) == 10
def test_xtheme_editor_form_picture(admin_user, browser, live_server, settings): """ Test that is is possible to add image fron media browser """ browser = initialize_admin_browser_test(browser, live_server, settings) browser.visit(live_server + "/") wait_until_condition(browser, lambda x: page_has_loaded(x), timeout=20) wait_until_appeared(browser, ".xt-edit-toggle button[type='submit']") click_element(browser, ".xt-edit-toggle button[type='submit']") placeholder_selector = "#xt-ph-front_content-xtheme-person-contact-layout" wait_until_condition( browser, lambda x: x.is_element_present_by_css(placeholder_selector)) click_element(browser, placeholder_selector) with browser.get_iframe("xt-edit-sidebar-iframe") as iframe: # make sure all scripts are loaded wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) wait_until_condition(iframe, lambda x: x.is_text_present("front_content")) wait_until_appeared(iframe, "button.layout-add-row-btn") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # click to add a new row click_element(iframe, "button.layout-add-row-btn") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # select the last row (the added one) click_element(iframe, "button.layout-add-row-btn") iframe.find_by_css("div.layout-cell").last.click() time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # select the TextPlugin wait_until_appeared(iframe, "select[name='general-plugin']") iframe.select("general-plugin", "text") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) wait_until_appeared(iframe, "ul.editor-tabs") filer_image = factories.get_random_filer_image() wait_until_appeared( browser, "#id_plugin-text_en-editor-wrap button[aria-label='Picture']") click_element( browser, "#id_plugin-text_en-editor-wrap button[aria-label='Picture']") wait_until_condition(browser, lambda b: len(b.windows) == 2, timeout=20) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") browser.find_by_css("a.file-preview").first.click() # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] # make sure the image was added to the editor wait_until_appeared( browser, "#id_plugin-text_en-editor-wrap .note-editable img[src='%s']" % filer_image.url, timeout=20)
def test_product_media_api(admin_user): shop = get_default_shop() client = _get_client(admin_user) product = create_product("product", shop=shop) # create 2 images for product, 1 with contents, other with external url image = get_random_filer_image() media = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, file=image, enabled=True, public=True) media_external = ProductMedia.objects.create(product=product, kind=ProductMediaKind.IMAGE, external_url="http://www.myimage.com/img.gif", enabled=True, public=True) product.primary_image = media product.save() # get product media response = client.get("/api/shuup/product_media/%d/" % media.pk) media_data = json.loads(response.content.decode("utf-8")) assert media_data["kind"] == media.kind.value assert media_data["product"] == product.pk assert media_data["public"] == media.public assert media_data["id"] == media.pk # get external media response = client.get("/api/shuup/product_media/%d/" % media_external.pk) media_data = json.loads(response.content.decode("utf-8")) assert media_data["kind"] == media_external.kind.value assert media_data["product"] == product.pk assert media_data["public"] == media_external.public assert media_data["id"] == media_external.pk assert media_data["external_url"] == media_external.external_url # update product media image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) media_data = { "translations": { "en": {"title": "title 2", "description": "desc2"} }, "shops": [shop.pk], "kind": ProductMediaKind.IMAGE.value, "file": uri, "path": "/what/the/zzzz" } response = client.put("/api/shuup/product_media/%d/" % media.pk, content_type="application/json", data=json.dumps(media_data)) assert response.status_code == status.HTTP_200_OK media.refresh_from_db() assert media.title == media_data["translations"]["en"]["title"] assert media.description == media_data["translations"]["en"]["description"] assert media.shops.count() == len(media_data["shops"]) assert set(media.shops.all().values_list("pk", flat=True)) >= set(media_data["shops"]) assert media.kind.value == media_data["kind"] assert media.file.folder.pretty_logical_path == media_data["path"] with open(media.file.path, 'rb') as f: assert img_base64 == base64.b64encode(f.read()).decode() media_count = product.media.count() # deletes an image response = client.delete("/api/shuup/product_media/%d/" % media.pk) assert response.status_code == status.HTTP_204_NO_CONTENT assert media_count-1 == product.media.count()
def test_xtheme_editor_form_picture(admin_user, browser, live_server, settings): """ Test that is is possible to add image fron media browser """ browser = initialize_admin_browser_test(browser, live_server, settings) browser.visit(live_server + "/") wait_until_condition(browser, lambda x: page_has_loaded(x), timeout=20) wait_until_appeared(browser, ".xt-edit-toggle button[type='submit']") click_element(browser, ".xt-edit-toggle button[type='submit']") placeholder_selector = "#xt-ph-front_content-xtheme-person-contact-layout" wait_until_condition(browser, lambda x: x.is_element_present_by_css(placeholder_selector)) click_element(browser, placeholder_selector) with browser.get_iframe("xt-edit-sidebar-iframe") as iframe: # make sure all scripts are loaded wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) wait_until_condition(iframe, lambda x: x.is_text_present("front_content")) wait_until_appeared(iframe, "button.layout-add-row-btn") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # click to add a new row click_element(iframe, "button.layout-add-row-btn") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # select the last row (the added one) click_element(iframe, "button.layout-add-row-btn") iframe.find_by_css("div.layout-cell").last.click() time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) # select the TextPlugin wait_until_appeared(iframe, "select[name='general-plugin']") iframe.select("general-plugin", "text") time.sleep(1) wait_until_condition(iframe, lambda x: page_has_loaded(x), timeout=20) wait_until_appeared(iframe, "ul.editor-tabs") filer_image = factories.get_random_filer_image() wait_until_appeared(browser, "#id_plugin-text_en-editor-wrap button[aria-label='Picture']") click_element(browser, "#id_plugin-text_en-editor-wrap button[aria-label='Picture']") wait_until_condition(browser, lambda b: len(b.windows) == 2, timeout=20) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") browser.find_by_css("a.file-preview").first.click() # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] # make sure the image was added to the editor wait_until_appeared(browser, "#id_plugin-text_en-editor-wrap .note-editable img[src='%s']" % filer_image.url, timeout=20)
def test_category_api(admin_user): activate("en") shop = get_default_shop() client = APIClient() client.force_authenticate(user=admin_user) image = get_random_filer_image() with open(image.path, 'rb') as f: img_base64 = base64.b64encode(os.urandom(50)).decode() uri = "data:application/octet-stream;base64,{}".format(img_base64) category_data = { "shops": [shop.pk], "status": CategoryStatus.VISIBLE.value, "ordering": 1, "visibility": CategoryVisibility.VISIBLE_TO_ALL.value, "visible_in_menu": True, "translations": { "en": { "name": "Category 1" } }, "image_path": "/didnt/choose/path", "image": uri } response = client.post("/api/shuup/category/", content_type="application/json", data=json.dumps(category_data)) assert response.status_code == status.HTTP_201_CREATED category = Category.objects.first() assert category.name == category_data["translations"]["en"]["name"] assert category.status.value == category_data["status"] assert category.ordering == category_data["ordering"] assert category.visibility.value == category_data["visibility"] assert category.visible_in_menu == category_data["visible_in_menu"] assert category.shops.first().pk == shop.pk assert category.image.folder.pretty_logical_path == category_data[ "image_path"] with open(category.image.path, 'rb') as f: assert img_base64 == base64.b64encode(f.read()).decode() category_data.pop("image_path") # Test error when not sending a path response = client.post("/api/shuup/category/", content_type="application/json", data=json.dumps(category_data)) assert response.status_code == status.HTTP_400_BAD_REQUEST data = json.loads(response.content.decode("utf-8")) assert data["non_field_errors"][ 0] == "Path is required when sending a Category image." category_data["image_path"] = "/path/chose/me" category_data["translations"]["en"]["name"] = "name 2" category_data["ordering"] = 3 response = client.put("/api/shuup/category/%d/" % category.id, content_type="application/json", data=json.dumps(category_data)) assert response.status_code == status.HTTP_200_OK category = Category.objects.first() assert category.name == category_data["translations"]["en"]["name"] assert category.ordering == category_data["ordering"] response = client.get("/api/shuup/category/%d/" % category.id) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert category.name == data["translations"]["en"]["name"] assert category.status.value == data["status"] assert category.ordering == data["ordering"] assert category.visibility.value == data["visibility"] assert category.visible_in_menu == data["visible_in_menu"] response = client.get("/api/shuup/category/") assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert category.name == data[0]["translations"]["en"]["name"] assert category.ordering == data[0]["ordering"] response = client.get("/api/shuup/category/?status=%s" % CategoryStatus.VISIBLE.value) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert len(data) == 1 response = client.get("/api/shuup/category/?status=%s" % CategoryStatus.INVISIBLE.value) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert len(data) == 0 response = client.get("/api/shuup/category/?status=%s" % CategoryStatus.DELETED.value) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert len(data) == 0 # soft delete response = client.delete("/api/shuup/category/%d/" % category.id) assert response.status_code == status.HTTP_204_NO_CONTENT assert Category.objects.first().status == CategoryStatus.DELETED response = client.get("/api/shuup/category/?status=%s" % CategoryStatus.DELETED.value) assert response.status_code == status.HTTP_200_OK data = json.loads(response.content.decode("utf-8")) assert len(data) == 1
def test_carousel_multi_slide(browser, admin_user, live_server, settings): shop = factories.get_default_shop() filer_image = factories.get_random_filer_image() initialize_admin_browser_test(browser, live_server, settings, shop=shop) wait_until_condition(browser, lambda x: x.is_text_present("Welcome!")) assert not Carousel.objects.exists() browser.visit(live_server + "/sa/carousels/new") wait_until_condition(browser, lambda x: x.is_text_present("New Carousel")) browser.fill("base-name", "Carrot") click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']") assert Carousel.objects.count() == 1 carousel = Carousel.objects.first() browser.visit(live_server + "/sa/carousels/%d/" % carousel.pk) wait_until_condition(browser, lambda x: x.is_text_present(carousel.name)) click_element(browser, "a[href='#slides-section']") wait_until_appeared(browser, ".slide-add-new-panel") # add 4 slides click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") click_element(browser, ".slide-add-new-panel") wait_until_condition(browser, lambda x: x.is_text_present("Slide 3")) # delete slide3 wait_until_appeared(browser, "a[href='#collapse3']") click_element(browser, "a[href='#collapse3']") wait_until_appeared(browser, "#collapse3 .btn-remove-slide") click_element(browser, "#collapse3 .btn-remove-slide") wait_until_condition(browser, lambda x: not x.is_text_present("Slide 3")) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "a[href='#slides-section'].errors") click_element(browser, "a[href='#slides-section']") for slide_id in [0, 1, 2]: wait_until_appeared(browser, "a[href='#collapse%d']" % (slide_id + 1)) click_element(browser, "a[href='#collapse%d']" % (slide_id + 1)) browser.find_by_css("[name='slides-%d-caption__en']" % slide_id).fill("Slide") click_element(browser, "[name='slides-%d-category_link'] + .select2" % slide_id) wait_until_appeared( browser, ".select2-container #select2-id_slides-%d-category_link-results li" % slide_id) click_element( browser, ".select2-container #select2-id_slides-%d-category_link-results li:last-child" % slide_id) browser.find_by_css("#id_slides-%d-image__en-dropzone" % slide_id).click() wait_until_condition(browser, lambda b: len(b.windows) == 2) # change to the media browser window browser.windows.current = browser.windows[1] # click to select the picture wait_until_appeared(browser, "a.file-preview") click_element(browser, "a.file-preview") # back to the main window wait_until_condition(browser, lambda b: len(b.windows) == 1) browser.windows.current = browser.windows[0] wait_until_appeared(browser, ".dz-image img[alt='%s']" % filer_image.name) click_element(browser, "button[form='carousel_form']") wait_until_appeared(browser, "div[class='message success']")