def test_cultivar_bad_slugs(self, app, db):
     """Return 404 if any slug given does not correspond to a db entry."""
     app.config["SHOW_CULTIVAR_PAGES"] = True
     idx = Index()
     cn = CommonName()
     cultivar = Cultivar()
     db.session.add_all([idx, cn, cultivar])
     idx.name = "Perennial Flower"
     cn.name = "Foxglove"
     cultivar.name = "Foxy"
     cultivar.common_name = cn
     cultivar.description = "Like that Hendrix song."
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug=idx.slug, cn_slug=cn.slug, cv_slug="no-biscuit"))
     assert rv.status_code == 404
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug="no_biscuit", cn_slug=cn.slug, cv_slug=cultivar.slug))
     assert rv.status_code == 404
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug=idx.slug, cn_slug="no-biscuit", cv_slug=cultivar.slug))
     assert rv.status_code == 404
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug="no-biscuit", cn_slug="no-biscuit", cv_slug="no-biscuit"))
     assert rv.status_code == 404
 def test_add_cultivar_successful_submit_no_stock_and_inactive(self, mock_save, app, db):
     """Flash messages if cultivar is not in stock and has been dropped."""
     bn = BotanicalName()
     cn = CommonName()
     idx = Index()
     db.session.add_all([bn, cn, idx])
     bn.name = "Digitalis purpurea"
     idx.name = "Perennial Flower"
     cn.name = "Foxglove"
     cn.index = idx
     bn.common_names.append(cn)
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.post(
             url_for("seeds.add_cultivar", cn_id=cn.id),
             data=dict(
                 botanical_name=str(bn.id),
                 index=str(idx.id),
                 description="Very foxy.",
                 active="",
                 in_stock="",
                 name="Foxy",
                 section="0",
                 thumbnail=(io.BytesIO(b"fawks"), "foxy.jpg"),
             ),
             follow_redirects=True,
         )
     assert '"Foxy Foxglove" is not in stock' in str(rv.data)
     assert '"Foxy Foxglove" is currently inactive' in str(rv.data)
Exemplo n.º 3
0
 def test_queryable_dict(self):
     """Return a dict containing the name and index of a CommonName."""
     cn = CommonName()
     assert cn.queryable_dict == {'Common Name': None, 'Index': None}
     cn.name = 'Foxglove'
     assert cn.queryable_dict == {'Common Name': 'Foxglove', 'Index': None}
     cn.index = Index(name='Perennial')
     assert cn.queryable_dict == {'Common Name': 'Foxglove',
                                  'Index': 'Perennial'}
 def test_remove_common_name_renders_page(self, app, db):
     """Render seeds/remove_common_name.html given valid cn_id."""
     cn = CommonName()
     db.session.add(cn)
     cn.name = "Coleus"
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.remove_common_name", cn_id=cn.id))
     assert rv.status_code == 200
     assert "Remove Common Name" in str(rv.data)
Exemplo n.º 5
0
 def test_init(self, m_sfc):
     m_sfc.return_value = [(1, "One"), (2, "Two"), (3, "Three")]
     cn1 = CommonName(name="One")
     cn1.id = 1
     cn2 = CommonName(name="Two")
     cn2.id = 2
     obj = BotanicalName(name="Bot nam")
     obj.common_names = [cn1, cn2]
     ebnf = EditBotanicalNameForm(obj=obj)
     assert ebnf.common_names.data == [1, 2]
Exemplo n.º 6
0
 def test_html_botanical_names_with_bns(self):
     """Return a list of botanical names formatted for use on webpage."""
     cn = CommonName(name='Foxglove')
     cn.botanical_names = [BotanicalName(name='Digitalis purpurea'),
                           BotanicalName(name='Digitalis über alles'),
                           BotanicalName(name='Digitalis does dallas')]
     assert cn.html_botanical_names == (
         'Digitalis purpurea, '
         '<abbr title="Digitalis">D.</abbr> über alles, '
         '<abbr title="Digitalis">D.</abbr> does dallas'
     )
Exemplo n.º 7
0
 def test_queryable_dicts_to_json_bad_args(self):
     """Raise a TypeError if any objects lack the lookup_dict method."""
     with pytest.raises(TypeError):
         queryable_dicts_to_json((1, 2, 3))
     cn1 = CommonName(name='Foxglove')
     cn1.index = Index(name='Perennial')
     cn2 = CommonName(name='Coleus')
     cn2.index = Index(name='Annual')
     idx = Index(name='Has no lookup_dict')
     with pytest.raises(TypeError):
         queryable_dicts_to_json((cn1, cn2, idx))
 def test_common_name_bad_slugs(self, app, db):
     """Give a 404 page if given malformed cn_slug and idx_slug."""
     cn = CommonName()
     idx = Index()
     db.session.add_all([cn, idx])
     cn.name = "Foxglove"
     idx.name = "Perennial Flower"
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.common_name", idx_slug="pewennial-flower", cn_slug="fawksglove"))
     assert rv.status_code == 404
 def test_select_common_name_success(self, app, db):
     """Redirect to dest with cn_id selected by form."""
     cn = CommonName()
     db.session.add(cn)
     cn.name = "Coleus"
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.post(
             url_for("seeds.select_common_name", dest="seeds.edit_common_name"), data=dict(common_name=cn.id)
         )
     assert rv.status_code == 302
     assert rv.location == url_for("seeds.edit_common_name", cn_id=cn.id, _external=True)
 def test_add_botanical_name_bad_cn_id(self, app, db):
     """Redirect to select common name if CommonName can't be loaded."""
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.add_botanical_name"))
     assert rv.location == url_for("seeds.select_common_name", dest="seeds.add_botanical_name", _external=True)
     cn = CommonName()
     cn.id = 1
     db.session.add(cn)
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.add_botanical_name", cn_id=42))
     assert rv.location == url_for("seeds.select_common_name", dest="seeds.add_botanical_name", _external=True)
 def test_add_section_bad_cn_id(self, app, db):
     """Redirect to select_common_name if cn_id is invalid."""
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.add_section"))
     assert rv.location == url_for("seeds.select_common_name", dest="seeds.add_section", _external=True)
     cn = CommonName(name="Foxglove")
     cn.id = 1
     db.session.add(cn)
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.add_section", cn_id=42))
     assert rv.location == url_for("seeds.select_common_name", dest="seeds.add_section", _external=True)
 def test_common_name_renders_page(self, app, db):
     """Render page with common name info given valid slugs."""
     cn = CommonName()
     idx = Index()
     db.session.add_all([cn, idx])
     cn.name = "Foxglove"
     cn.description = "Do foxes really wear these?"
     idx.name = "Perennial Flower"
     cn.index = idx
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.common_name", idx_slug=idx.slug, cn_slug=cn.slug))
     assert "Do foxes really wear these?" in str(rv.data)
 def test_gw_from_dict_(self, db):
     """Set grows_with with a list of ids from a CommonName.dict_"""
     a = CommonName(name='a')
     b = CommonName(name='b')
     c = CommonName(name='c')
     db.session.add_all([a, b, c])
     db.session.flush()
     cn = CommonName(name='Test')
     cn.gw_common_names = [a, b, c]
     d = cn.dict_
     cn2 = CommonName(name='Test2')
     cn2.gw_from_dict_(d)
     assert cn.gw_common_names == cn2.gw_common_names
Exemplo n.º 14
0
 def test_add_one_with_synonyms(self):
     """Add a BotanicalName with synonyms to Botanical Names sheet."""
     wb = Workbook()
     ws = wb.active
     bnws = BotanicalNamesWorksheet(ws)
     bnws.setup()
     bn = BotanicalName(name='Innagada davida')
     cn = CommonName(name='Rock')
     cn.index = Index(name='Music')
     bn.common_names = [cn]
     bn.synonyms_string = 'Iron butterfly'
     bnws.add_one(bn)
     assert bnws.cell(2, bnws.cols['Synonyms']).value == 'Iron butterfly'
 def test_gw_from_dict_missing_cns(self, db):
     """Raise a RuntimeError if any needed CNs are missing."""
     a = CommonName(name='a')
     b = CommonName(name='b')
     c = CommonName(name='c')
     db.session.add_all([a, b, c])
     db.session.flush()
     cn = CommonName(name='Test')
     cn.gw_common_names = [a, b, c]
     d = cn.dict_
     d['gw_common_names'].append(42)
     cn2 = CommonName(name='Test2')
     with pytest.raises(RuntimeError):
         cn2.gw_from_dict_(d)
Exemplo n.º 16
0
 def test_validate_botanical_name_id(self, m_bnq):
     """Raise error if selected BN is not in selected CN."""
     bn = BotanicalName("Digitalis über alles")
     cn1 = CommonName(name="Fauxglove")
     cn1.id = 1
     cn2 = CommonName(name="Spuriousglove")
     cn2.id = 2
     bn.common_names = [cn1, cn2]
     m_bnq.return_value = bn
     self = mock.MagicMock()
     self.common_name_id.data = 3
     field = mock.MagicMock()
     with pytest.raises(ValidationError):
         EditCultivarForm.validate_botanical_name_id(self=self, field=field)
Exemplo n.º 17
0
def set_related_links():
    with open('/tmp/related_links.json', 'r', encoding='utf-8') as ifile:
        dicts = json.loads(ifile.read())
        print('Setting related links/grows with...')
        for d in dicts:
            cn = CommonName.from_slugs(
                d['source']['idx_slug'],
                d['source']['cn_slug']
            )
            if d['target']['anchor']:
                t = Cultivar.from_slugs(
                    d['target']['idx_slug'],
                    d['target']['cn_slug'],
                    d['target']['anchor']
                )
                if t:
                    cn.gw_cultivars.append(t)
                else:
                    t = Section.from_slugs(
                        d['target']['idx_slug'],
                        d['target']['cn_slug'],
                        d['target']['anchor']
                    )
                    if t:
                        cn.gw_sections.append(t)
                    else:
                        print(
                            'Could not find a Section or Cultivar with the '
                            'slug: "{}"'.format(d['target']['anchor'])
                        )
                        t = CommonName.from_slugs(
                            d['target']['idx_slug'],
                            d['target']['cn_slug']
                        )
                        cn.gw_common_names.append(t)
            else:
                t = CommonName.from_slugs(
                    d['target']['idx_slug'],
                    d['target']['cn_slug']
                )
                if t:
                    cn.gw_common_names.append(t)
                else:
                    print('Could not find gw for {}'.format(d))
            if t:
                print(
                    '"{}" grows with the {} "{}"'
                    .format(cn.name, t.__class__.__name__, t.name)
                )
        db.session.commit()
def foxy_cultivar():
    """Generate a Cultivar object based on Foxy Foxglove."""
    cultivar = Cultivar()
    cultivar.name = "Foxy"
    cultivar.description = "Not to be confused with that Hendrix song."
    bn = BotanicalName()
    bn.name = "Digitalis purpurea"
    cultivar.botanical_name = bn
    idx = Index()
    idx.name = "Perennial Flower"
    cn = CommonName()
    cn.name = "Foxglove"
    cn.index = idx
    cultivar.common_name = cn
    return cultivar
 def test_get_or_create_get(self, db):
     cn = CommonName(name='Foxglove', index=Index(name='Perennial'))
     db.session.add(cn)
     db.session.commit()
     assert CommonName.get_or_create(name='Foxglove',
                                     index='Perennial') is cn
     assert not cn.created
Exemplo n.º 20
0
def generate_common_names(idx, l):
    for d in l:
        cn = CommonName.get_or_create(d['name'], idx)
        db.session.add(cn)
        cn.list_as = d['list_as']
        cn.slug = d['slug']
        cn.subtitle = d['subtitle']
        cn.sunlight = d['sunlight']
        cn.thumbnail = download_image(d['thumb_url'])
        cn.botanical_names = d['botanical_names']
        cn.description = d['description']
        cn.instructions = d['instructions']
        if not cn.cultivars:
            cn.cultivars = []
        for cv in generate_cultivars(cn, d['cultivars']):
            if cv not in cn.cultivars:
                cn.cultivars.append(cv)
        if not cn.sections:
            cn.sections = []
        for s in generate_sections(cn, d['sections']):
            if s not in cn.sections:
                cn.sections.append(s)
        db.session.flush()
        cn.child_sections.reorder()
        cn.child_cultivars.reorder()
        yield cn
Exemplo n.º 21
0
 def test_add_one_with_optionals(self):
     """Add a common name with optionals to Common Names sheet."""
     wb = Workbook()
     ws = wb.active
     cnws = CommonNamesWorksheet(ws)
     cnws.setup()
     cn = CommonName(name='Foxglove',
                     description='Spotty.',
                     instructions='Just add water!')
     cn.index = Index(name='Perennial')
     cn.synonyms_string = 'Digitalis'
     cnws.add_one(cn)
     assert cnws.cell(2, cnws.cols['Description']).value == 'Spotty.'
     assert cnws.cell(
         2, cnws.cols['Planting Instructions']
     ).value == 'Just add water!'
     assert cnws.cell(2, cnws.cols['Synonyms']).value == 'Digitalis'
 def test_get_or_create_create_with_existing_index(self, db):
     idx = Index(name='Perennial')
     db.session.add(idx)
     db.session.commit()
     cn = CommonName.get_or_create(name='Foxglove', index='Perennial')
     assert cn.created
     assert cn.index is idx
     assert not idx.created
Exemplo n.º 23
0
    def save_row_to_db(self, row, stream=sys.stdout):
        """Save a row from the Common Names sheet to the database.

        Args:
            row: The number of the row to save.
            stream: Optional IO stream to print messages to.

        Returns:
            bool: `True` if changes have been made, `False` if not.
        """
        cn_json = self.cell(row, self.cols['Common Name (JSON)']).value
        cn_dict = json.loads(cn_json)
        section = dbify(self.cell(row, self.cols['Section']).value)
        description = self.cell(row, self.cols['Description']).value

        print('-- BEGIN editing/creating Section \'{0}\' from row #{1}. '
              '--'.format(section, row), file=stream)
        edited = False
        cn = CommonName.get_or_create(name=dbify(cn_dict['Common Name']),
                                      index=dbify(cn_dict['Index']),
                                      stream=stream)
        sec = None
        if not cn.created:
            sec = Section.query\
                .filter(Section.name == section, Section.common_name_id == cn.id)\
                .one_or_none()
        if sec:
            print('The Section \'{0}\' has been loaded from the database.'
                  .format(sec.name), file=stream)
        else:
            edited = True
            sec = Section(name=section)
            sec.common_name = cn
            print('CommonName for the Section \'{0}\' set to: {1}'
                  .format(sec.name, cn.name), file=stream)
            db.session.add(sec)
            print('The Section \'{0}\' does not yet exist in the database, '
                  'so it has been created.'.format(sec.name), file=stream)
        if description != sec.description:
            edited = True
            if description:
                sec.description = description
                print('Description for the Section \'{0}\' set to: {1}'
                      .format(sec.name, sec.description), file=stream)
            else:
                sec.description = None
                print('Description for the Section \'{0}\' has been cleared.'
                      .format(sec.name), file=stream)
        if edited:
            db.session.flush()
            print('Changes to the Section \'{0}\' have been flushed to '
                  'the database.'.format(sec.name), file=stream)
        else:
            print('No changes were made to the Section \'{0}\'.'
                  .format(sec.name), file=stream)
        print('-- END editing/creating Section \'{0}\' from row #{1}. '
              '--'.format(sec.name, row), file=stream)
        return edited
Exemplo n.º 24
0
 def test_add_one_no_optionals(self):
     """Add a common name (with no optional data) to Common Names sheet."""
     messages = StringIO()
     wb = Workbook()
     ws = wb.active
     cnws = CommonNamesWorksheet(ws)
     cnws.setup()
     cn = CommonName(name='Foxglove')
     cn.index = Index(name='Perennial')
     cnws.add_one(cn, stream=messages)
     assert cnws.cell(2, cnws.cols['Index']).value == 'Perennial'
     assert cnws.cell(2, cnws.cols['Common Name']).value == 'Foxglove'
     assert cnws.cell(2, cnws.cols['Description']).value is None
     assert cnws.cell(2, cnws.cols['Planting Instructions']).value is None
     assert cnws.cell(2, cnws.cols['Synonyms']).value is None
     messages.seek(0)
     msgs = messages.read()
     assert ('Adding data from <CommonName "Foxglove"> to row #2 of '
             'common names worksheet.') in msgs
 def test_remove_common_name_not_verified(self, app, db):
     """Redirect to self with flash if verify_removal not checked."""
     cn = CommonName()
     cn2 = CommonName()
     db.session.add_all([cn, cn2])
     cn.name = "Coleus"
     cn2.name = "Kingus"
     db.session.commit()
     assert cn in CommonName.query.all()
     with app.test_client() as tc:
         rv = tc.post(url_for("seeds.remove_common_name", cn_id=cn.id), data=dict(verify_removal="", move_to=cn2.id))
     assert rv.location == url_for("seeds.remove_common_name", cn_id=cn.id, _external=True)
     with app.test_client() as tc:
         rv = tc.post(
             url_for("seeds.remove_common_name", cn_id=cn.id),
             data=dict(verify_removal="", move_to=cn2.id),
             follow_redirects=True,
         )
     assert "Common name was not removed" in str(rv.data)
     assert cn in CommonName.query.all()
 def test_cv_slugs_not_in_cultivar(self, app, db):
     """Return 404 if slugs return db entries, but entry not in cultivar."""
     app.config["SHOW_CULTIVAR_PAGES"] = True
     idx1 = Index()
     idx2 = Index()
     cn1 = CommonName()
     cn2 = CommonName()
     cultivar = Cultivar()
     db.session.add_all([idx1, idx2, cn1, cn2, cultivar])
     idx1.name = "Perennial Flower"
     idx2.name = "Long Hair"
     cn1.name = "Foxglove"
     cn2.name = "Persian"
     cultivar.name = "Foxy"
     cultivar.common_name = cn1
     db.session.commit()
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug=idx1.slug, cn_slug=cn2.slug, cv_slug=cultivar.slug))
     assert rv.status_code == 404
     with app.test_client() as tc:
         rv = tc.get(url_for("seeds.cultivar", idx_slug=idx2.slug, cn_slug=cn1.slug, cv_slug=cultivar.slug))
     assert rv.status_code == 404
Exemplo n.º 27
0
 def test_add_one_no_optionals(self):
     """Add a BotanicalName object to Botanical Names sheet."""
     messages = StringIO()
     wb = Workbook()
     ws = wb.active
     bnws = BotanicalNamesWorksheet(ws)
     bnws.setup()
     bn = BotanicalName(name='Innagada davida')
     cn = CommonName(name='Rock')
     cn.index = Index(name='Music')
     bn.common_names = [cn]
     bnws.add_one(bn, stream=messages)
     assert bnws.cell(
         2, bnws.cols['Common Names (JSON)']
     ).value == queryable_dicts_to_json([cn])
     assert bnws.cell(
         2, bnws.cols['Botanical Name']
     ).value == 'Innagada davida'
     assert bnws.cell(2, bnws.cols['Synonyms']).value is None
     messages.seek(0)
     msgs = messages.read()
     assert ('Adding data from <BotanicalName "Innagada davida"> to row '
             '#2 of botanical names worksheet.') in msgs
Exemplo n.º 28
0
    def test_queryable_dicts_to_json(self):
        """Generate a JSON string for looking up Grows With cns/cvs.

        It can take either, as both have the queryable_dict method.
        """
        gwcn1 = CommonName(name='Foxglove')
        gwcn1.index = Index(name='Perennial')
        assert queryable_dicts_to_json([gwcn1]) == \
            json.dumps((gwcn1.queryable_dict,))
        gwcn2 = CommonName(name='Butterfly Weed')
        gwcn2.index = Index(name='Perennial')
        assert queryable_dicts_to_json([gwcn1, gwcn2]) == \
            json.dumps((gwcn1.queryable_dict, gwcn2.queryable_dict))
        gwcv1 = Cultivar(name='Soulmate')
        gwcv1.common_name = CommonName(name='Butterfly Weed')
        gwcv1.common_name.index = Index(name='Perennial')
        assert queryable_dicts_to_json([gwcv1]) == \
            json.dumps((gwcv1.queryable_dict,))
        gwcv2 = Cultivar(name='Petra')
        gwcv2.common_name = CommonName(name='Foxglove')
        gwcv2.common_name.index = Index(name='Perennial')
        gwcv2.section = Section(name='Polkadot')
        assert queryable_dicts_to_json([gwcv1, gwcv2]) == \
            json.dumps((gwcv1.queryable_dict, gwcv2.queryable_dict))
Exemplo n.º 29
0
    def test_dict__to_from_dict_(self, m_iq, m_cq):
        """Create new CommonName equal to CN.dict_

        Note:

        grows_with is excluded because that must be handled by a different
        function.
        """
        m_cq.get.return_value = None
        cn = CommonName()
        idx = Index()
        m_iq.get.return_value = idx
        idx.id = 1
        cn.id = 42
        cn.index = idx
        cn.name = 'Annual'
        cn.slug = 'annual'
        cn.description = 'Not built to last.'
        cn.instructions = 'Plant them.'
        cn.visible = True
        d = cn.dict_
        assert CommonName.from_dict_(d)
 def test_remove_common_name_verified(self, app, db):
     """Delete CommonName from db on successful submit."""
     cn = CommonName()
     cn2 = CommonName()
     idx = Index(name="Perennial")
     db.session.add_all([idx, cn, cn2])
     cn.name = "Coleus"
     cn.index = idx
     cn2.name = "Kingus"
     cn2.index = idx
     db.session.commit()
     assert cn in CommonName.query.all()
     with app.test_client() as tc:
         tc.post(
             url_for("seeds.remove_common_name", cn_id=cn.id),
             data=dict(verify_removal=True, move_to=cn2.id),
             follow_redirects=True,
         )
     assert cn not in CommonName.query.all()