xref: /aosp_15_r20/external/toolchain-utils/cros_utils/email_sender_unittest.py (revision 760c253c1ed00ce9abd48f8546f08516e57485fe)
1*760c253cSXin Li#!/usr/bin/env python3
2*760c253cSXin Li# -*- coding: utf-8 -*-
3*760c253cSXin Li
4*760c253cSXin Li# Copyright 2020 The ChromiumOS Authors
5*760c253cSXin Li# Use of this source code is governed by a BSD-style license that can be
6*760c253cSXin Li# found in the LICENSE file.
7*760c253cSXin Li
8*760c253cSXin Li"""Tests for email_sender."""
9*760c253cSXin Li
10*760c253cSXin Li
11*760c253cSXin Liimport contextlib
12*760c253cSXin Liimport io
13*760c253cSXin Liimport json
14*760c253cSXin Liimport unittest
15*760c253cSXin Liimport unittest.mock as mock
16*760c253cSXin Li
17*760c253cSXin Liimport cros_utils.email_sender as email_sender
18*760c253cSXin Li
19*760c253cSXin Li
20*760c253cSXin Liclass Test(unittest.TestCase):
21*760c253cSXin Li    """Tests for email_sender."""
22*760c253cSXin Li
23*760c253cSXin Li    @mock.patch("cros_utils.email_sender.AtomicallyWriteFile")
24*760c253cSXin Li    def test_x20_email_sending_rejects_invalid_inputs(self, write_file):
25*760c253cSXin Li        test_cases = [
26*760c253cSXin Li            {
27*760c253cSXin Li                # no subject
28*760c253cSXin Li                "subject": "",
29*760c253cSXin Li                "identifier": "foo",
30*760c253cSXin Li                "direct_recipients": ["[email protected]"],
31*760c253cSXin Li                "text_body": "hi",
32*760c253cSXin Li            },
33*760c253cSXin Li            {
34*760c253cSXin Li                "subject": "foo",
35*760c253cSXin Li                # no identifier
36*760c253cSXin Li                "identifier": "",
37*760c253cSXin Li                "direct_recipients": ["[email protected]"],
38*760c253cSXin Li                "text_body": "hi",
39*760c253cSXin Li            },
40*760c253cSXin Li            {
41*760c253cSXin Li                "subject": "foo",
42*760c253cSXin Li                "identifier": "foo",
43*760c253cSXin Li                # no recipients
44*760c253cSXin Li                "direct_recipients": [],
45*760c253cSXin Li                "text_body": "hi",
46*760c253cSXin Li            },
47*760c253cSXin Li            {
48*760c253cSXin Li                "subject": "foo",
49*760c253cSXin Li                "identifier": "foo",
50*760c253cSXin Li                "direct_recipients": ["[email protected]"],
51*760c253cSXin Li                # no body
52*760c253cSXin Li            },
53*760c253cSXin Li            {
54*760c253cSXin Li                "subject": "foo",
55*760c253cSXin Li                "identifier": "foo",
56*760c253cSXin Li                # direct recipients lack @google.
57*760c253cSXin Li                "direct_recipients": ["gbiv"],
58*760c253cSXin Li                "text_body": "hi",
59*760c253cSXin Li            },
60*760c253cSXin Li            {
61*760c253cSXin Li                "subject": "foo",
62*760c253cSXin Li                "identifier": "foo",
63*760c253cSXin Li                # non-list recipients
64*760c253cSXin Li                "direct_recipients": "[email protected]",
65*760c253cSXin Li                "text_body": "hi",
66*760c253cSXin Li            },
67*760c253cSXin Li            {
68*760c253cSXin Li                "subject": "foo",
69*760c253cSXin Li                "identifier": "foo",
70*760c253cSXin Li                # non-list recipients
71*760c253cSXin Li                "well_known_recipients": "detective",
72*760c253cSXin Li                "text_body": "hi",
73*760c253cSXin Li            },
74*760c253cSXin Li        ]
75*760c253cSXin Li
76*760c253cSXin Li        sender = email_sender.EmailSender()
77*760c253cSXin Li        for case in test_cases:
78*760c253cSXin Li            with self.assertRaises(ValueError):
79*760c253cSXin Li                sender.SendX20Email(**case)
80*760c253cSXin Li
81*760c253cSXin Li        write_file.assert_not_called()
82*760c253cSXin Li
83*760c253cSXin Li    @mock.patch("cros_utils.email_sender.AtomicallyWriteFile")
84*760c253cSXin Li    def test_x20_email_sending_translates_to_reasonable_json(self, write_file):
85*760c253cSXin Li        written_obj = None
86*760c253cSXin Li
87*760c253cSXin Li        @contextlib.contextmanager
88*760c253cSXin Li        def actual_write_file(file_path):
89*760c253cSXin Li            nonlocal written_obj
90*760c253cSXin Li
91*760c253cSXin Li            self.assertTrue(
92*760c253cSXin Li                file_path.startswith(email_sender.X20_PATH + "/"), file_path
93*760c253cSXin Li            )
94*760c253cSXin Li            f = io.StringIO()
95*760c253cSXin Li            yield f
96*760c253cSXin Li            written_obj = json.loads(f.getvalue())
97*760c253cSXin Li
98*760c253cSXin Li        write_file.side_effect = actual_write_file
99*760c253cSXin Li        email_sender.EmailSender().SendX20Email(
100*760c253cSXin Li            subject="hello",
101*760c253cSXin Li            identifier="world",
102*760c253cSXin Li            well_known_recipients=["detective"],
103*760c253cSXin Li            direct_recipients=["[email protected]"],
104*760c253cSXin Li            text_body="text",
105*760c253cSXin Li            html_body="html",
106*760c253cSXin Li        )
107*760c253cSXin Li
108*760c253cSXin Li        self.assertEqual(
109*760c253cSXin Li            written_obj,
110*760c253cSXin Li            {
111*760c253cSXin Li                "subject": "hello",
112*760c253cSXin Li                "email_identifier": "world",
113*760c253cSXin Li                "well_known_recipients": ["detective"],
114*760c253cSXin Li                "direct_recipients": ["[email protected]"],
115*760c253cSXin Li                "body": "text",
116*760c253cSXin Li                "html_body": "html",
117*760c253cSXin Li            },
118*760c253cSXin Li        )
119*760c253cSXin Li
120*760c253cSXin Li
121*760c253cSXin Liif __name__ == "__main__":
122*760c253cSXin Li    unittest.main()
123