Repository: getmoto/moto

Issue:
mock_events: `Archive` contains events that do not match `EventPattern`
**How to reproduce:**

```py
@mock_events
def test_event_not_routed_to_archive_when_detail_does_not_match_pattern():
    # given
    client = boto3.client("events", "eu-central-1")
    event_bus_arn = "arn:aws:events:eu-central-1:{}:event-bus/default".format(
        ACCOUNT_ID
    )
    client.create_archive(
        ArchiveName="no-matches-detail",
        EventSourceArn=event_bus_arn,
        EventPattern=json.dumps({
            "detail": {"foo": ["baz"]}
        })
    )

    # when
    event = {
        "Source": "source",
        "DetailType": "type",
        "Detail": '{"foo": "baz"}'
    }
    client.put_events(Entries=[event])

    # then
    response = client.describe_archive(ArchiveName="no-matches-detail")
    response["EventCount"].should.equal(0)
    response["SizeBytes"].should.equal(0)
```

**Expected behaviour:**

Since the Detail of the event does not match the archive's EventPattern, I would expect there to be no events in the archive and therefore for the test to pass.


**Actual behaviour:**

```
self = 'X is 1 whereas Y is 0', X = 1, Y = 0

    def as_assertion(self, X, Y):
>       raise self.get_assertion(X, Y)
E       AssertionError: given
E       X = 1
E           and
E       Y = 0
E       X is 1 whereas Y is 0

venv/lib/python3.8/site-packages/sure/core.py:57: AssertionError

During handling of the above exception, another exception occurred:

    @mock_events
    def test_event_not_routed_to_archive_when_detail_does_not_match_pattern():
        # given
        client = boto3.client("events", "eu-central-1")
        event_bus_arn = "arn:aws:events:eu-central-1:{}:event-bus/default".format(
            ACCOUNT_ID
        )
        client.create_archive(
            ArchiveName="no-matches-detail",
            EventSourceArn=event_bus_arn,
            EventPattern=json.dumps({
                "detail": {"foo": ["baz"]}
            })
        )
    
        # when
        event = {
            "Source": "source",
            "DetailType": "type",
            "Detail": '{"foo": "baz"}'
        }
        client.put_events(Entries=[event])
    
        # then
        response = client.describe_archive(ArchiveName="no-matches-detail")
>       response["EventCount"].should.equal(0)

tests/test_events/test_events.py:1346: 
```

**Note:**
I'm planning to raise a PR fixing the issue soon


Discussion:

Resolving patch:
diff --git a/moto/events/models.py b/moto/events/models.py
--- a/moto/events/models.py
+++ b/moto/events/models.py
@@ -92,6 +92,24 @@ def remove_targets(self, ids):
             if index is not None:
                 self.targets.pop(index)
 
+    def _does_event_match_pattern(self, event, pattern):
+        if not pattern:
+            return True
+        event_pattern_pairs = [(event.get(k), v) for k, v in pattern.items()]
+        for event_item, pattern_item in event_pattern_pairs:
+            if not self._does_event_item_match_pattern_item(event_item, pattern_item):
+                return False
+        return True
+
+    def _does_event_item_match_pattern_item(self, event_item, pattern_item):
+        #  Only supports "key: [value]" filters currently
+        if not event_item:
+            return False
+        if isinstance(pattern_item, list):
+            return event_item in pattern_item
+        if isinstance(pattern_item, dict):
+            return self._does_event_match_pattern(event_item, pattern_item)
+
     def send_to_targets(self, event_bus_name, event):
         event_bus_name = event_bus_name.split("/")[-1]
         if event_bus_name != self.event_bus_name:
@@ -186,9 +204,12 @@ def _send_to_cw_log_group(self, name, event):
     def _send_to_events_archive(self, resource_id, event):
         archive_name, archive_uuid = resource_id.split(":")
         archive = events_backends[self.region_name].archives.get(archive_name)
-
+        pattern = archive.event_pattern
         if archive.uuid == archive_uuid:
-            archive.events.append(event)
+            event = json.loads(json.dumps(event))
+            pattern = json.loads(pattern) if pattern else None
+            if self._does_event_match_pattern(event, pattern):
+                archive.events.append(event)
 
     def _send_to_sqs_queue(self, resource_id, event):
         from moto.sqs import sqs_backends


Test patch:
diff --git a/tests/test_events/test_events.py b/tests/test_events/test_events.py
--- a/tests/test_events/test_events.py
+++ b/tests/test_events/test_events.py
@@ -1488,6 +1488,59 @@ def test_archive_event_with_bus_arn():
     response["SizeBytes"].should.be.greater_than(0)
 
 
+@mock_events
+def test_event_not_routed_to_archive_when_detail_does_not_match_pattern():
+    # given
+    client = boto3.client("events", "eu-central-1")
+    event_bus_arn = "arn:aws:events:eu-central-1:{}:event-bus/default".format(
+        ACCOUNT_ID
+    )
+    client.create_archive(
+        ArchiveName="archive-with-dict-filter",
+        EventSourceArn=event_bus_arn,
+        EventPattern=json.dumps({"detail": {"foo": ["bar"]}}),
+    )
+    client.create_archive(
+        ArchiveName="archive-with-list-filter",
+        EventSourceArn=event_bus_arn,
+        EventPattern=json.dumps({"source": ["foo", "bar"]}),
+    )
+
+    # when
+    event_matching_detail = {
+        "Source": "source",
+        "DetailType": "type",
+        "Detail": '{"foo": "bar"}',
+    }
+    event_not_matching_detail = {
+        "Source": "source",
+        "DetailType": "type",
+        "Detail": '{"foo": "baz"}',
+    }
+    event_matching_source_foo = {"Source": "foo", "DetailType": "type", "Detail": "{}"}
+    event_matching_source_bar = {"Source": "bar", "DetailType": "type", "Detail": "{}"}
+    event_not_matching_source = {"Source": "baz", "DetailType": "type", "Detail": "{}"}
+
+    client.put_events(
+        Entries=[
+            event_matching_detail,
+            event_not_matching_detail,
+            event_matching_source_foo,
+            event_matching_source_bar,
+            event_not_matching_source,
+        ]
+    )
+
+    # then
+    response = client.describe_archive(ArchiveName="archive-with-dict-filter")
+    response["EventCount"].should.equal(1)
+    response["SizeBytes"].should.be.greater_than(0)
+
+    response = client.describe_archive(ArchiveName="archive-with-list-filter")
+    response["EventCount"].should.equal(2)
+    response["SizeBytes"].should.be.greater_than(0)
+
+
 @mock_events
 def test_start_replay():
     # given