def test_occupied_nest_number(self):
        self.assertEqual(
            int(self.observation_json["observers"][0]["protocol"]
                ["occupied_nest_number"]["@id"]),
            self.observation.occupied_nest_number,
        )

        observation_json = {
            "observers": [{
                "protocol": {
                    "occupied_nest_number": "123",
                },
            }]
        }
        self.assertEqual(
            int(observation_json["observers"][0]["protocol"]
                ["occupied_nest_number"]),
            Observation.create_from_ornitho_json(
                observation_json).occupied_nest_number,
        )

        observation_json = {"observers": [{}]}
        self.assertIsNone(
            Observation.create_from_ornitho_json(
                observation_json).occupied_nest_number)
 def test_by_observer(self):
     Observation.list = MagicMock(return_value=["obs", "pk"])
     Observation.by_observer(id_observer=1)
     Observation.list.assert_called_with(request_all=False,
                                         pagination_key=None,
                                         short_version=False,
                                         id_observer=1)
    def test_diff(self):
        Observation.request = MagicMock(return_value=[
            {
                "id_sighting": "1",
                "id_universal": "1",
                "modification_type": "updated",
            },
            {
                "id_sighting": "2",
                "id_universal": "2",
                "modification_type": "deleted",
            },
        ])

        # Case 1: without retrieving
        date = datetime.now() - timedelta(hours=1)
        observations = Observation.diff(
            date,
            modification_type=ModificationType.ALL,
            id_taxo_group=1,
            only_protocol="CBBM",
            only_form=True,
        )
        self.assertEqual(len(observations), 2)
        Observation.request.assert_called_with(
            method="get",
            url="observations/diff",
            params={
                "date": date.replace(microsecond=0).isoformat(),
                "modification_type": ModificationType.ALL.value,
                "id_taxo_group": "1",
                "only_protocol": "CBBM",
                "only_form": "1",
            },
        )

        # Case 2: with retrieving

        mock_protocol = MagicMock(spec=ornitho.Protocol)
        type(mock_protocol).name = mock.PropertyMock(return_value="CBBM-Mock")
        Observation.get = MagicMock(return_value=self.observation)
        date = datetime.now().astimezone(
            pytz.timezone("Asia/Tokyo")) - timedelta(hours=1)
        observations = Observation.diff(date,
                                        only_protocol=mock_protocol,
                                        retrieve_observations=True)
        self.assertEqual(len(observations), 2)
        self.assertEqual(observations[0], self.observation)
        Observation.request.assert_called_with(
            method="get",
            url="observations/diff",
            params={
                "date":
                date.replace(microsecond=0).astimezone(
                    datetime.now().astimezone().tzinfo).replace(
                        tzinfo=None).isoformat(),
                "only_protocol":
                "CBBM-Mock",
            },
        )
    def test_mark_as_exported(self, mock_updateable_model, mock_base_model):
        self.observation.mark_as_exported()
        mock_updateable_model.assert_called_once()
        self.observation.mark_as_exported(datetime.now())
        mock_updateable_model.assert_called()
        self.assertEqual(2, mock_updateable_model.call_count)

        obs = Observation()
        obs.mark_as_exported()
        mock_base_model.assert_called_once()
    def test_id_species(self):
        self.assertEqual(int(self.observation_json["species"]["@id"]),
                         self.observation.id_species)

        obs = Observation()
        obs._raw_data = {"species": {"id": 1}}
        self.assertEqual(1, obs.id_species)

        obs.id_species = 2
        self.assertEqual(2, obs.id_species)
    def test_hidden(self):
        self.assertFalse(self.observation.hidden)

        obs = Observation()
        hidden = True
        obs.hidden = hidden
        self.assertTrue(obs.hidden)
        hidden2 = False
        obs.hidden = hidden2
        self.assertFalse(obs.hidden_comment)
    def test_place(self):
        place = self.observation.place
        self.assertEqual(place._raw_data, self.observation_json["place"])

        with mock.patch("ornitho.model.observation.Place") as mock_place:
            mock_place.get.return_value = "Place"
            mock_place.id_.return_value = "1"
            obs = Observation()
            obs.place = mock_place
            self.assertEqual(mock_place.id_, obs.place.id_)
    def test_is_exported(self):
        self.assertTrue(self.observation.is_exported)
        self.observation.is_exported = False
        self.assertFalse(self.observation.is_exported)
        self.observation.is_exported = True
        self.assertTrue(self.observation.is_exported)

        observation = Observation()
        self.assertFalse(observation.is_exported)
        observation.is_exported = True
        self.assertTrue(observation.is_exported)
    def test_count(self):
        self.assertEqual(int(self.observation_json["observers"][0]["count"]),
                         self.observation.count)

        obs = Observation()
        count = 1
        obs.count = count
        self.assertEqual(count, obs.count)
        count2 = 2
        obs.count = count2
        self.assertEqual(count2, obs.count)
    def test_id_atlas_code(self):
        self.assertEqual(
            self.observation_json["observers"][0]["atlas_code"]["@id"],
            self.observation.id_atlas_code,
        )

        obs = Observation()
        obs.id_atlas_code = "3_1"
        self.assertEqual("3_1", obs.id_atlas_code)

        obs.id_atlas_code = "3_2"
        self.assertEqual("3_2", obs.id_atlas_code)
    def test_observation_detail(self, mock_field_option):
        mock_field_option.get.return_value = "Observation Detail retrieved"
        mock_field_option.id_.return_value = "4_1"

        observation_detail = self.observation.observation_detail
        mock_field_option.get.assert_called_with(
            self.observation.id_observation_detail)
        self.assertEqual(observation_detail, "Observation Detail retrieved")

        obs = Observation()
        obs.observation_detail = mock_field_option
        self.assertEqual(mock_field_option.id_, obs.observation_detail.id_)
    def test_create_from(self):
        observation = Observation.create_from_ornitho_json(
            self.observation_json)
        self.assertEqual(43050307, observation.id_)
        self.assertEqual(self.observation_json, observation._raw_data)

        # Test Exception
        self.assertRaises(
            APIException,
            lambda: Observation.create_from_ornitho_json(
                {"observers": ["1", "2"]}),
        )
    def test_atlas_code(self, mock_field_option):
        mock_field_option.get.return_value = "Atlas Code retrieved"
        mock_field_option.id_.return_value = "2"

        atlas_code = self.observation.atlas_code
        mock_field_option.get.assert_called_with(
            f"3_{self.observation.id_atlas_code}")
        self.assertEqual(atlas_code, "Atlas Code retrieved")

        obs = Observation()
        obs.atlas_code = mock_field_option
        self.assertEqual(mock_field_option.id_, obs.atlas_code.id_)
    def test_resting_habitat(self, mock_field_option):
        mock_field_option.get.return_value = "Resting habitat retrieved"
        mock_field_option.id_.return_value = "1_1"

        resting_habitat = self.observation.resting_habitat
        mock_field_option.get.assert_called_with(
            self.observation.id_resting_habitat)
        self.assertEqual(resting_habitat, "Resting habitat retrieved")

        obs = Observation()
        obs.resting_habitat = mock_field_option
        self.assertEqual(mock_field_option.id_, obs.resting_habitat.id_)
 def test_id_form(self):
     self.assertEqual(
         int(self.observation_json["observers"][0]["id_form"]),
         self.observation.id_form,
     )
     obs = Observation()
     id_form = 1
     obs.id_form = id_form
     self.assertEqual(id_form, obs.id_form)
     id_form2 = 2
     obs.id_form = id_form2
     self.assertEqual(id_form2, obs.id_form)
    def test_export_date(self):
        self.observation.is_exported = False
        self.assertIsNone(self.observation.export_date)
        now = datetime.now().astimezone().replace(microsecond=0)
        self.observation.is_exported = True
        self.observation.export_date = now
        self.assertEqual(now, self.observation.export_date)

        observation = Observation()
        observation.export_date = now
        observation.is_exported = True
        self.assertEqual(now, observation.export_date)
    def test_observer(self):
        observer = self.observation.observer
        self.assertEqual(observer._raw_data,
                         self.observation_json["observers"][0])

        with mock.patch("ornitho.model.observation.Observer") as mock_observer:
            mock_observer.id_.return_value = 1
            mock_observer._raw_data.return_value = {"id": 1}
            mock_observer.get.return_value = mock_observer

            obs = Observation()
            obs.observer = mock_observer
            self.assertEqual(mock_observer.get.return_value, obs.observer)
    def test_coord_lon(self):
        self.assertEqual(
            float(self.observation_json["observers"][0]["coord_lon"]),
            self.observation.coord_lon,
        )

        obs = Observation()
        coord_lon = 1.23
        obs.coord_lon = coord_lon
        self.assertEqual(coord_lon, obs.coord_lon)
        coord_lon2 = 2.34
        obs.coord_lon = coord_lon2
        self.assertEqual(coord_lon2, obs.coord_lon)
    def test_altitude(self):
        self.assertEqual(
            int(self.observation_json["observers"][0]["altitude"]),
            self.observation.altitude,
        )

        obs = Observation()
        altitude = 1
        obs.altitude = altitude
        self.assertEqual(altitude, obs.altitude)
        altitude2 = 2
        obs.altitude = altitude2
        self.assertEqual(altitude2, obs.altitude)
    def test_comment(self):
        self.assertEqual(
            self.observation_json["observers"][0]["comment"],
            self.observation.comment,
        )

        obs = Observation()
        comment = "comment"
        obs.comment = comment
        self.assertEqual(comment, obs.comment)
        comment2 = "comment2"
        obs.comment = comment2
        self.assertEqual(comment2, obs.comment)
    def test_precision(self):
        self.assertEqual(
            Precision(self.observation_json["observers"][0]["precision"]),
            self.observation.precision,
        )

        obs = Observation()
        precision = Precision.PRECISE
        obs.precision = precision
        self.assertEqual(precision, obs.precision)
        precision2 = Precision.PLACE
        obs.precision = precision2
        self.assertEqual(precision2, obs.precision)
    def test_hidden_comment(self):
        self.assertEqual(
            self.observation_json["observers"][0]["hidden_comment"],
            self.observation.hidden_comment,
        )

        obs = Observation()
        hidden_comment = "hidden_comment"
        obs.hidden_comment = hidden_comment
        self.assertEqual(hidden_comment, obs.hidden_comment)
        hidden_comment2 = "hidden_comment2"
        obs.hidden_comment = hidden_comment2
        self.assertEqual(hidden_comment2, obs.hidden_comment)
    def test_coord_lat(self):
        self.assertEqual(
            float(self.observation_json["observers"][0]["coord_lat"]),
            self.observation.coord_lat,
        )

        obs = Observation()
        coord_lat = 1.23
        obs.coord_lat = coord_lat
        self.assertEqual(coord_lat, obs.coord_lat)
        coord_lat2 = 2.34
        obs.coord_lat = coord_lat2
        self.assertEqual(coord_lat2, obs.coord_lat)
    def test_estimation_code(self):
        self.assertEqual(
            EstimationCode(
                self.observation_json["observers"][0]["estimation_code"]),
            self.observation.estimation_code,
        )

        obs = Observation()
        estimation_code = EstimationCode.EXACT_VALUE
        obs.estimation_code = estimation_code
        self.assertEqual(estimation_code, obs.estimation_code)
        estimation_code2 = EstimationCode.ESTIMATION
        obs.estimation_code = estimation_code2
        self.assertEqual(estimation_code2, obs.estimation_code)
    def test_guid(self):
        self.assertEqual(
            uuid.UUID(self.observation_json["observers"][0]["guid"]),
            self.observation.guid,
        )

        obs = Observation()
        guid = uuid.uuid4()
        obs.guid = guid
        self.assertEqual(guid, obs.guid)

        guid2 = uuid.uuid4()
        obs.guid = guid2
        self.assertEqual(guid2, obs.guid)
    def test_notime(self):
        self.assertFalse(self.observation.notime)
        self.observation.notime = True
        self.assertTrue(self.observation.notime)

        observation = Observation()
        observation.notime = True
        self.assertTrue(observation.notime)

        observation = Observation.create_from_ornitho_json(
            {"observers": [{
                "id_sighting": 42
            }]})
        observation.notime = True
        self.assertTrue(observation.notime)
    def test_details(self):
        details = [Detail(1, "U", "PULL"), Detail(12, "M", "AD")]
        self.assertEqual(details, self.observation.details)

        obs_json = {
            "observers": [{
                "id_sighting":
                "44874562",
                "details": [
                    {
                        "count": "1",
                        "sex": {
                            "@id": "U",
                            "#text": "unbekannt"
                        },
                        "age": {
                            "@id": "PULL",
                            "#text": "Pullus / nicht-flügge"
                        },
                    },
                    {
                        "count": "12",
                        "sex": {
                            "@id": "M",
                            "#text": "Männchen"
                        },
                        "age": {
                            "@id": "AD",
                            "#text": "adult"
                        },
                    },
                ],
            }]
        }
        self.assertEqual(
            details,
            Observation.create_from_ornitho_json(obs_json).details)

        obs = Observation()
        obs.details = details
        self.assertEqual(details, obs.details)
        details2 = [
            Detail(1, "U", "PULL"),
            Detail(12, "M", "AD"),
            Detail(4, "F", "AD")
        ]
        obs.details = details2
        self.assertEqual(details2, obs.details)
    def test_medias(self, mock_media):
        mock_media.get.return_value = "Media retrieved"

        self.assertIsNone(self.observation.medias)

        obs_json = {
            "observers": [{
                "id_sighting":
                "44874562",
                "medias": [
                    {
                        "@id": "111111",
                    },
                    {
                        "@id": "2222222",
                    },
                ],
            }]
        }
        obs = Observation.create_from_ornitho_json(obs_json)
        medias = obs.medias
        self.assertIsNotNone(medias)
        self.assertEqual(len(obs_json["observers"][0]["medias"]), len(medias))
        mock_media.get.assert_called_with(
            obs_json["observers"][0]["medias"][1]["@id"])
    def test_media_urls(self):
        self.assertIsNone(self.observation.media_urls)

        obs_json = {
            "observers": [{
                "id_sighting":
                "44874562",
                "medias": [
                    {
                        "@id": "111111",
                        "path": "https://test.media/www.ornitho.de/1970-01",
                        "filename": "file1.jpg",
                    },
                    {
                        "@id": "2222222",
                        "path": "https://test.media/www.ornitho.de/1970-01",
                        "filename": "file2.jpg",
                    },
                ],
            }]
        }
        obs = Observation.create_from_ornitho_json(obs_json)
        media_urls = obs.media_urls
        self.assertIsNotNone(media_urls)
        self.assertEqual(len(obs_json["observers"][0]["medias"]),
                         len(media_urls))
        self.assertEqual(
            f"{obs_json['observers'][0]['medias'][0]['path']}/{obs_json['observers'][0]['medias'][0]['filename']}",
            media_urls[0],
        )
        self.assertEqual(
            f"{obs_json['observers'][0]['medias'][1]['path']}/{obs_json['observers'][0]['medias'][1]['filename']}",
            media_urls[1],
        )
    def test_timing(self):
        self.assertEqual(
            datetime.fromtimestamp(
                int(self.observation_json["observers"][0]["timing"]
                    ["@timestamp"]),
                datetime.now().astimezone().tzinfo,
            ),
            self.observation.timing,
        )

        obs = Observation()
        now = datetime.now().replace(microsecond=0)
        obs.timing = now
        self.assertEqual(now.astimezone(), obs.timing)
        now2 = datetime.now().replace(microsecond=0).astimezone()
        obs.timing = now2
        self.assertEqual(now2, obs.timing)