Repository: uccser/cs-unplugged

Issue:
Add a static resource to Error detection and correction > 13 digit product code check digits
Error Detection and Correction > Product code check digits > Ages 8 to 10 > Add the following resource so that teachers can print.


https://drive.google.com/file/d/0B-SN1PgPBbCYQ2g5ZlJRX1plYmc/view?usp=sharing


Discussion:

Resolving patch:
diff --git a/csunplugged/resources/views/barcode_checksum_poster.py b/csunplugged/resources/views/barcode_checksum_poster.py
new file mode 100644
--- /dev/null
+++ b/csunplugged/resources/views/barcode_checksum_poster.py
@@ -0,0 +1,55 @@
+"""Module for generating Barcode Checksum Poster resource."""
+
+from PIL import Image
+from utils.retrieve_query_parameter import retrieve_query_parameter
+
+
+def resource_image(request, resource):
+    """Create a image for Barcode Checksum Poster resource.
+
+    Args:
+        request: HTTP request object (QueryDict).
+        resource: Object of resource data (Resource).
+
+    Returns:
+        A list of Pillow image objects.
+    """
+    # Retrieve parameters
+    parameter_options = valid_options()
+    barcode_length = retrieve_query_parameter(request, "barcode_length", parameter_options["barcode_length"])
+
+    image_path = "static/img/resources/barcode-checksum-poster/{}-digits.png"
+    image = Image.open(image_path.format(barcode_length))
+    return image
+
+
+def subtitle(request, resource):
+    """Return the subtitle string of the resource.
+
+    Used after the resource name in the filename, and
+    also on the resource image.
+
+    Args:
+        request: HTTP request object (QueryDict).
+        resource: Object of resource data (Resource).
+
+    Returns:
+        Text for subtitle (str).
+    """
+    barcode_length = retrieve_query_parameter(request, "barcode_length")
+    paper_size = retrieve_query_parameter(request, "paper_size")
+    return "{} digits - {}".format(barcode_length, paper_size)
+
+
+def valid_options():
+    """Provide dictionary of all valid parameters.
+
+    This excludes the header text parameter.
+
+    Returns:
+        All valid options (dict).
+    """
+    return {
+        "barcode_length": ["12", "13"],
+        "paper_size": ["a4", "letter"],
+    }


Test patch:
diff --git a/csunplugged/tests/resources/urls/test_barcode_checksum_poster.py b/csunplugged/tests/resources/urls/test_barcode_checksum_poster.py
new file mode 100644
--- /dev/null
+++ b/csunplugged/tests/resources/urls/test_barcode_checksum_poster.py
@@ -0,0 +1,19 @@
+from tests.BaseTestWithDB import BaseTestWithDB
+from django.urls import reverse
+
+
+class BarcodeChecksumPosterResourceURLTest(BaseTestWithDB):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.language = "en"
+        self.RESOURCE_SLUG = "barcode-checksum-poster"
+        self.RESOURCE_URL_KWARGS = {"resource_slug": self.RESOURCE_SLUG}
+
+    def test_valid_barcode_checksum_poster_resource_url(self):
+        url = reverse("resources:resource", kwargs=self.RESOURCE_URL_KWARGS)
+        self.assertEqual(url, "/en/resources/barcode-checksum-poster/")
+
+    def test_valid_barcode_checksum_poster_resource_generate_url(self):
+        url = reverse("resources:generate", kwargs=self.RESOURCE_URL_KWARGS)
+        self.assertEqual(url, "/en/resources/barcode-checksum-poster/generate")
diff --git a/csunplugged/tests/resources/views/test_barcode_checksum_poster.py b/csunplugged/tests/resources/views/test_barcode_checksum_poster.py
new file mode 100644
--- /dev/null
+++ b/csunplugged/tests/resources/views/test_barcode_checksum_poster.py
@@ -0,0 +1,120 @@
+from django.urls import reverse
+from tests.BaseTestWithDB import BaseTestWithDB
+from tests.resources.ResourcesTestDataGenerator import ResourcesTestDataGenerator
+from utils.import_resource_module import import_resource_module
+from utils.create_query_string import query_string
+from utils.resource_valid_test_configurations import resource_valid_test_configurations
+
+
+class BarcodeChecksumPosterResourceViewTest(BaseTestWithDB):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+        self.test_data = ResourcesTestDataGenerator()
+        self.language = "en"
+
+    def test_barcode_checksum_poster_resource_form_view(self):
+        resource = self.test_data.create_resource(
+            "barcode-checksum-poster",
+            "Barcode Checksum Poster",
+            "resources/barcode-checksum-poster.html",
+            "barcode_checksum_poster.py",
+        )
+        kwargs = {
+            "resource_slug": resource.slug,
+        }
+        url = reverse("resources:resource", kwargs=kwargs)
+        response = self.client.get(url)
+        self.assertEqual(200, response.status_code)
+
+    def test_barcode_checksum_poster_resource_generation_valid_configurations(self):
+        resource = self.test_data.create_resource(
+            "barcode-checksum-poster",
+            "Barcode Checksum Poster",
+            "resources/barcode-checksum-poster.html",
+            "barcode_checksum_poster.py",
+        )
+        kwargs = {
+            "resource_slug": resource.slug,
+        }
+        base_url = reverse("resources:generate", kwargs=kwargs)
+        resource_module = import_resource_module(resource)
+        valid_options = resource_module.valid_options()
+        combinations = resource_valid_test_configurations(valid_options)
+        print()
+        for combination in combinations:
+            print("   - Testing combination: {} ... ".format(combination), end="")
+            url = base_url + query_string(combination)
+            response = self.client.get(url)
+            self.assertEqual(200, response.status_code)
+            subtitle = "{} digits - {}".format(
+                combination["barcode_length"],
+                combination["paper_size"],
+            )
+            self.assertEqual(
+                response.get("Content-Disposition"),
+                'attachment; filename="Resource Barcode Checksum Poster ({subtitle}).pdf"'.format(subtitle=subtitle)
+            )
+            print("ok")
+
+    def test_barcode_checksum_poster_resource_generation_missing_barcode_length_parameter(self):
+        resource = self.test_data.create_resource(
+            "barcode-checksum-poster",
+            "Barcode Checksum Poster",
+            "resources/barcode-checksum-poster.html",
+            "barcode_checksum_poster.py",
+        )
+        kwargs = {
+            "resource_slug": resource.slug,
+        }
+        url = reverse("resources:generate", kwargs=kwargs)
+        get_parameters = {
+            "paper_size": "a4",
+            "header_text": "",
+        }
+        url += query_string(get_parameters)
+        response = self.client.get(url)
+        self.assertEqual(404, response.status_code)
+
+    def test_binary_cards_small_resource_generation_missing_paper_size_parameter(self):
+        resource = self.test_data.create_resource(
+            "barcode-checksum-poster",
+            "Barcode Checksum Poster",
+            "resources/barcode-checksum-poster.html",
+            "barcode_checksum_poster.py",
+        )
+        kwargs = {
+            "resource_slug": resource.slug,
+        }
+        url = reverse("resources:generate", kwargs=kwargs)
+        get_parameters = {
+            "barcode_length": "12",
+            "header_text": "",
+        }
+        url += query_string(get_parameters)
+        response = self.client.get(url)
+        self.assertEqual(404, response.status_code)
+
+    def test_binary_cards_small_resource_generation_missing_header_text_parameter(self):
+        resource = self.test_data.create_resource(
+            "barcode-checksum-poster",
+            "Barcode Checksum Poster",
+            "resources/barcode-checksum-poster.html",
+            "barcode_checksum_poster.py",
+        )
+        kwargs = {
+            "resource_slug": resource.slug,
+        }
+        url = reverse("resources:generate", kwargs=kwargs)
+        get_parameters = {
+            "barcode_length": "12",
+            "paper_size": "a4",
+        }
+        url += query_string(get_parameters)
+        response = self.client.get(url)
+        self.assertEqual(200, response.status_code)
+        filename = "Resource Barcode Checksum Poster (12 digits - a4).pdf"
+        self.assertEqual(
+            response.get("Content-Disposition"),
+            'attachment; filename="{}"'.format(filename)
+        )