Exemple #1
0
 def test_viewpoint_search_city(self):
     list_url = reverse("terra_opp:viewpoint-list")
     city = CityFactory(label="Rouperou-le-coquet")
     city2 = CityFactory(label="New york")
     city3 = CityFactory(label="Los angeles")
     ViewpointFactory(
         label="Viewpoint for search",
         pictures__state="accepted",
         city=city,
         active=True,
     )
     ViewpointFactory(
         label="Not found",
         pictures__state="accepted",
         city=city2,
         active=True,
     )
     ViewpointFactory(
         label="Not found also",
         pictures__state="accepted",
         city=city3,
         active=True,
     )
     self.assertEqual(self.client.get(list_url).json()["count"], 4)
     data = self.client.get(list_url, {"city_id": city.id}).json()
     self.assertEqual(data.get("count"), 1)
     data = self.client.get(list_url, {"city": "Rouperou-le-coquet"}).json()
     self.assertEqual(data.get("count"), 1)
Exemple #2
0
 def test_viewpoint_search_themes(self):
     list_url = reverse("terra_opp:viewpoint-list")
     theme_foo = ThemeFactory(label="foo")
     theme_bar = ThemeFactory(label="bar")
     theme_baz = ThemeFactory(label="baz")
     theme_not = ThemeFactory(label="not")
     vp = ViewpointFactory(
         label="Viewpoint for search",
         pictures__state="accepted",
         properties={
             "voie": "coin d'en bas de la rue du bout",
             "site": "Carrière des petits violoncelles",
         },
         active=True,
     )
     vp.themes.add(theme_foo, theme_bar, theme_baz)
     self.assertEqual(self.client.get(list_url).json()["count"], 2)
     data = self.client.get(list_url, {"themes_id": [theme_foo.id]}).json()
     self.assertEqual(data.get("count"), 1)
     data = self.client.get(list_url, {"themes": ["foo"]}).json()
     self.assertEqual(data.get("count"), 1)
     data = self.client.get(
         list_url, {"themes_id": [theme_bar.id, theme_foo.id]}
     ).json()
     self.assertEqual(data.get("count"), 1)
     data = self.client.get(
         list_url, {"themes_id": [theme_bar.id, theme_not.id]}
     ).json()
     self.assertEqual(data.get("count"), 0)
Exemple #3
0
 def test_anonymous_options_request_returns_correct_search_filters(self):
     city1 = CityFactory(label="Montcuq")
     city2 = CityFactory(label="Rouperou-le-coquet")
     theme1 = ThemeFactory(label="Bar")
     theme2 = ThemeFactory(label="foo")
     ViewpointFactory(
         city=city1,
         themes=[theme1, theme2],
     )
     ViewpointFactory(
         city=city2,
         themes=[theme1],
     )
     data = self.client.get(reverse("terra_opp:viewpoint-filters")).json()
     self.assertEqual(data.get("cities"), ["Montcuq", "Rouperou-le-coquet"])
     self.assertEqual(data.get("themes"), ["Bar", "foo"])
Exemple #4
0
 def setUpTestData(cls):
     cls.feature = FeatureFactory()
     cls.user = TerraUserFactory()
     # Create viewpoint with draft picture attached to it
     cls.viewpoint = ViewpointFactory(label="Basic viewpoint")
     # Create viewpoint with accepted picture attached to it
     cls.viewpoint_with_accepted_picture = ViewpointFactory(
         label="Viewpoint with accepted picture",
         pictures__state="accepted",
         properties={"test_update": "ko"},
         active=True,
     )
     # Create viewpoints with no picture attached to it
     cls.viewpoint_without_picture = ViewpointFactory(
         label="Viewpoint without picture",
         pictures=None,
         properties={"test_update": "ko"},
     )
Exemple #5
0
    def test_post_campaign(self):
        data = {
            "label": "My campaign",
            "start_date": "2021-01-25",
            "assignee": self.photograph.pk,
            "viewpoints": [ViewpointFactory().pk,
                           ViewpointFactory().pk],
        }

        self.as_photograph()

        response = self.client.post(reverse("terra_opp:campaign-list"), data)
        self.assertEqual(status.HTTP_403_FORBIDDEN, response.status_code)

        self.as_admin()

        response = self.client.post(reverse("terra_opp:campaign-list"), data)

        self.assertEqual(status.HTTP_201_CREATED, response.status_code)
Exemple #6
0
    def test_only_active_viewpoint_retrieve(self):
        active_viewpoint = ViewpointFactory(
            label="Active viewpoint",
            active=True,
            pictures__state="accepted",
        )
        inactive_viewpoint = ViewpointFactory(
            label="Unactive viewpoint",
            active=False,
            pictures__state="accepted",
        )
        response = self.client.get(reverse("terra_opp:viewpoint-active"))
        self.assertEqual(status.HTTP_200_OK, response.status_code)

        active_viewpoint_count = (
            Viewpoint.objects.with_accepted_pictures().filter(active=True).count()
        )
        data = response.json()

        self.assertEqual(active_viewpoint_count, data["count"])
        self.assertNotIn(inactive_viewpoint.id, [d["id"] for d in data["results"]])
        self.assertIn(active_viewpoint.id, [d["id"] for d in data["results"]])
Exemple #7
0
 def test_viewpoint_search_json(self):
     list_url = reverse("terra_opp:viewpoint-list")
     ViewpointFactory(
         label="Viewpoint for search",
         pictures__state="accepted",
         properties={
             "voie": "coin d'en bas de la rue du bout",
             "site": "Carrière des petits violoncelles",
         },
         active=True,
     )
     self.assertEqual(self.client.get(list_url).json()["count"], 2)
     data = self.client.get(list_url, {"properties__voie": "rue"}).json()
     self.assertEqual(data.get("count"), 1)
     data = self.client.get(list_url, {"properties__site": "carrière"}).json()
     self.assertEqual(data.get("count"), 1)
Exemple #8
0
    def test_search_campaign(self):
        viewpoint = ViewpointFactory(pictures__state="accepted")

        campaign = CampaignFactory(assignee=self.photograph)
        campaign.viewpoints.set([viewpoint])

        CampaignFactory(assignee=self.photograph, state="started")
        CampaignFactory(assignee=self.photograph, state="closed")

        picture = PictureFactory(state="draft",
                                 viewpoint=viewpoint,
                                 campaign=campaign)

        list_url = resolve_url("terra_opp:campaign-list")

        self.as_admin()

        response = self.client.get(list_url, {"state": "draft"})
        self.assertEqual(1, response.data.get("count"))

        response = self.client.get(list_url, {"state": "started"})
        self.assertEqual(1, response.data.get("count"))

        response = self.client.get(list_url, {"state": "closed"})
        self.assertEqual(1, response.data.get("count"))

        response = self.client.get(list_url, {"state": "foo"})
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        response = self.client.get(list_url, {"pictures__state": "draft"})
        self.assertEqual(1, response.data.get("count"))
        response = self.client.get(list_url, {"pictures__state": "accepted"})
        self.assertEqual(0, response.data.get("count"))

        picture.state = "accepted"
        picture.save()

        response = self.client.get(list_url, {"pictures__state": "draft"})
        self.assertEqual(0, response.data.get("count"))
        response = self.client.get(list_url, {"pictures__state": "accepted"})
        self.assertEqual(1, response.data.get("count"))

        response = self.client.get(list_url, {"pictures__state": "foo"})
        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Exemple #9
0
    def test_auto_close(self):
        viewpoint = ViewpointFactory(pictures__state="accepted")
        viewpoint2 = ViewpointFactory(pictures__state="accepted")

        campaign = CampaignFactory(assignee=self.photograph, state="started")
        campaign.viewpoints.set([viewpoint, viewpoint2])
        campaign_url = resolve_url("terra_opp:campaign-detail", pk=campaign.pk)

        data = {
            "viewpoint": viewpoint.pk,
            "date": timezone.datetime(2020, 8, 19, tzinfo=timezone.utc),
            "file": self._gen_file(),
            "state": "draft",
        }

        # Stats without any photo
        self.as_admin()

        response = self.client.get(campaign_url)

        def stats(response):
            return response.json().get("statistics")

        # Add draft photo
        self.as_photograph()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )
        data["viewpoint"] = viewpoint2.pk
        data["file"] = self._gen_file()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.as_admin()

        latest_picture = viewpoint.pictures.latest()
        latest_picture2 = viewpoint2.pictures.latest()

        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "accepted"},
        )

        # Should still be started
        response = self.client.get(campaign_url)
        self.assertEqual(
            response.json()["state"],
            "started",
        )

        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture2.pk],
            ),
            {"state": "accepted"},
        )

        # Should be closed after last accepted picture
        response = self.client.get(campaign_url)
        self.assertEqual(
            response.json()["state"],
            "closed",
        )
Exemple #10
0
    def test_list_campaign(self):
        viewpoint = ViewpointFactory()
        viewpoint2 = ViewpointFactory()
        campaign = CampaignFactory(assignee=self.photograph, state="started")
        campaign.viewpoints.set([viewpoint, viewpoint2])

        campaign_other = CampaignFactory(
            state="started")  # campaign for other photograph

        campaign_same_not_started = CampaignFactory(
            state="draft", assignee=self.photograph
        )  # campaign for same photograph but not started

        list_url = reverse("terra_opp:campaign-list")
        campaign_url = resolve_url("terra_opp:campaign-detail", pk=campaign.pk)
        campaign_other_url = resolve_url("terra_opp:campaign-detail",
                                         pk=campaign_other.pk)
        campaign_not_started_url = resolve_url("terra_opp:campaign-detail",
                                               pk=campaign_same_not_started.pk)

        # First we try as anonymous
        self.assertIn(
            self.client.get(list_url).status_code,
            [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN],
        )
        self.assertIn(
            self.client.get(campaign_url).status_code,
            [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN],
        )
        self.assertIn(
            self.client.get(campaign_other_url).status_code,
            [status.HTTP_401_UNAUTHORIZED, status.HTTP_403_FORBIDDEN],
        )

        # Then we try with can_add_pictures permission
        self.as_photograph()

        response = self.client.get(list_url)

        self.assertEqual(status.HTTP_200_OK, response.status_code)
        # Only one should be visible
        self.assertEqual(1, response.data.get("count"))

        response = self.client.get(campaign_url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)

        # Others campaigns should be forbidden
        self.assertEqual(status.HTTP_403_FORBIDDEN,
                         self.client.get(campaign_other_url).status_code)
        # Not started campaigns should forbidden
        self.assertEqual(
            status.HTTP_403_FORBIDDEN,
            self.client.get(campaign_not_started_url).status_code,
        )

        # Then as admin
        self.as_admin()

        response = self.client.get(list_url)
        self.assertEqual(status.HTTP_200_OK, response.status_code)
        self.assertEqual(response.data.get("count"), 3)

        campaign_response = self.client.get(campaign_url)
        self.assertEqual(status.HTTP_200_OK, campaign_response.status_code)

        self.assertNumQueries(3, lambda: self.client.get(campaign_url))

        self.assertEqual(status.HTTP_200_OK,
                         self.client.get(campaign_other_url).status_code)
        self.assertEqual(status.HTTP_200_OK,
                         self.client.get(campaign_not_started_url).status_code)
Exemple #11
0
    def test_statistics(self):
        viewpoint = ViewpointFactory(pictures__state="accepted")
        viewpoint2 = ViewpointFactory(pictures__state="accepted")
        viewpoint3 = ViewpointFactory(pictures__state="accepted")
        viewpoint4 = ViewpointFactory(pictures__state="accepted")

        campaign = CampaignFactory(assignee=self.photograph, state="started")
        campaign.viewpoints.set(
            [viewpoint, viewpoint2, viewpoint3, viewpoint4])
        campaign_url = resolve_url("terra_opp:campaign-detail", pk=campaign.pk)

        data = {
            "viewpoint": viewpoint.pk,
            "date": timezone.datetime(2020, 8, 19, tzinfo=timezone.utc),
            "file": self._gen_file(),
            "state": "draft",
        }

        # Stats without any photo
        self.as_admin()

        response = self.client.get(campaign_url)

        def stats(response):
            return response.json().get("statistics")

        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 4,
                "submited": 0,
                "accepted": 0
            },
        )

        # Add draft photo
        self.as_photograph()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        # Draft photo are considered as missing...
        self.as_admin()
        response = self.client.get(campaign_url)
        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 4,
                "submited": 0,
                "accepted": 0
            },
        )

        # ...But are listed
        self.assertEqual(
            response.json()["pictures"],
            [{
                "viewpoint": 14,
                "date": "2020-08-19T00:00:00Z",
                "id": 22,
                "state": "draft",
            }],
        )

        # Submit photo
        self.as_photograph()
        latest_picture = viewpoint.pictures.latest()
        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "submited"},
        )

        # Should have 1 submited
        self.as_admin()
        response = self.client.get(campaign_url)
        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 3,
                "submited": 1,
                "accepted": 0
            },
        )

        # Submit another photo
        self.as_photograph()
        data["viewpoint"] = viewpoint2.pk
        data["file"] = self._gen_file()
        data["state"] = "submited"
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        # Should have 2 submited
        self.as_admin()
        response = self.client.get(campaign_url)
        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 2,
                "submited": 2,
                "accepted": 0
            },
        )

        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "accepted"},
        )

        # One shoud be accepted
        response = self.client.get(campaign_url)
        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 2,
                "submited": 1,
                "accepted": 1
            },
        )
        self.assertEqual(
            response.json()["pictures"],
            [
                {
                    "viewpoint": 15,
                    "date": "2020-08-19T00:00:00Z",
                    "id": 23,
                    "state": "submited",
                },
                {
                    "viewpoint": 14,
                    "date": "2020-08-19T00:00:00Z",
                    "id": 22,
                    "state": "accepted",
                },
            ],
        )

        # Perf check 3 queries even if 2 images and 4 viewpoints
        # One for campaign, one for viewpoints, one for pictures
        self.assertNumQueries(3, lambda: self.client.get(campaign_url))

        latest_picture2 = viewpoint2.pictures.latest()

        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture2.pk],
            ),
            {"state": "refused"},
        )

        # Refused are considered as missing
        response = self.client.get(campaign_url)
        self.assertEqual(
            stats(response),
            {
                "total": 4,
                "missing": 3,
                "submited": 0,
                "accepted": 1
            },
        )
Exemple #12
0
    def test_workflow(self):
        viewpoint = ViewpointFactory()
        viewpoint2 = ViewpointFactory()

        campaign1 = CampaignFactory(assignee=self.photograph, state="started")
        campaign1.viewpoints.set([viewpoint, viewpoint2])

        data = {
            "viewpoint": viewpoint.pk,
            "date": timezone.datetime(2020, 8, 19, tzinfo=timezone.utc),
            "file": self._gen_file(),
            "state": "draft",
        }

        # Photograph post draft photo
        self.as_photograph()
        self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        latest_picture = viewpoint.pictures.latest()

        # Then submit the photo
        self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "submited"},
        )

        # Admin refuse the photo
        self.as_admin()
        self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "refused"},
        )

        # Photograph update the photo
        self.as_photograph()
        self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {
                "state": "submited",
                "file": self._gen_file()
            },
            format="multipart",
        )

        # Admin accept the photo
        self.as_admin()
        self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[latest_picture.pk],
            ),
            {"state": "accepted"},
        )

        latest_picture.refresh_from_db()
        self.assertEqual(latest_picture.state, "accepted")
Exemple #13
0
    def test_add_picture(self):
        viewpoint = ViewpointFactory()
        viewpoint2 = ViewpointFactory()
        viewpoint3 = ViewpointFactory()
        viewpoint4 = ViewpointFactory()
        viewpoint5 = ViewpointFactory()
        viewpoint6 = ViewpointFactory()

        campaign1 = CampaignFactory(assignee=self.photograph, state="started")
        campaign1.viewpoints.set([viewpoint, viewpoint2])
        initial_picture_count1 = viewpoint.pictures.count()

        campaign2 = CampaignFactory(assignee=self.photograph, state="draft")
        campaign2.viewpoints.set([viewpoint3, viewpoint4])

        campaign3 = CampaignFactory(state="started")
        campaign3.viewpoints.set([viewpoint5, viewpoint6])

        data = {
            "viewpoint": viewpoint.pk,
            "date": timezone.datetime(2020, 8, 19, tzinfo=timezone.utc),
            "file": self._gen_file(),
            "state": "draft",
        }

        self.as_photograph()

        # Nominal cases should works
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_201_CREATED)
        self.assertEqual(viewpoint.pictures.count(),
                         initial_picture_count1 + 1)
        self.assertEqual(
            viewpoint.pictures.latest().date,
            timezone.datetime(2020, 8, 19, tzinfo=timezone.utc),
        )
        self.assertEqual(
            viewpoint.pictures.latest().state,
            "draft",
        )

        # Should not allow to create second photo
        data["file"] = self._gen_file()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        # Should update picture but ignore accepted state
        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[viewpoint.pictures.latest().pk],
            ),
            {"state": "accepted"},
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_200_OK)
        self.assertEqual(response.data.get("state"), "draft")

        # Should update previous picture and change state
        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[viewpoint.pictures.latest().pk],
            ),
            {"state": "submited"},
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_200_OK)

        # Should not allow modification on submitted picture
        response = self.client.patch(
            reverse(
                "terra_opp:picture-detail",
                args=[viewpoint.pictures.latest().pk],
            ),
            {"state": "accepted"},
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)

        # Post to draft campaign
        data["viewpoint"] = viewpoint3.pk
        data["file"] = self._gen_file()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        # Post to started campaign for another assignee
        data["viewpoint"] = viewpoint5.pk
        data["file"] = self._gen_file()
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        # Post to started campaign but with bad viewpoint
        data["viewpoint"] = viewpoint5.pk
        data["file"] = self._gen_file()
        data["campaign"] = campaign1.pk
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)

        # Post to started campaign bad picture state
        data["viewpoint"] = viewpoint5.pk
        data["file"] = self._gen_file()
        data["campaign"] = campaign1.pk
        response = self.client.post(
            reverse("terra_opp:picture-list"),
            data,
            format="multipart",
        )

        self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
Exemple #14
0
 def setUpTestData(cls):
     # Create viewpoint with draft picture attached to it
     cls.viewpoint = ViewpointFactory(label="Basic viewpoint")