Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion carbon/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import

from carbon.app import people
from carbon.app import people, PersonFeed
from carbon.db import engine, session
31 changes: 31 additions & 0 deletions carbon/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from functools import partial

from lxml import etree as ET
from sqlalchemy.sql import select

from carbon.db import persons, session
Expand All @@ -15,3 +17,32 @@ def people():
with session() as conn:
for row in conn.execute(sql):
yield dict(zip(row.keys(), row))


def _ns(namespace, element):
return ET.QName(namespace, element)


SYMPLECTIC_NS = 'http://www.symplectic.co.uk/hrimporter'
NSMAP = {None: SYMPLECTIC_NS}
ns = partial(_ns, SYMPLECTIC_NS)


def add_child(parent, element, text, **kwargs):
"""Add a subelement with text."""
child = ET.SubElement(parent, ns(element), nsmap=NSMAP, attrib=kwargs)
child.text = text
return child


class PersonFeed(object):
def __init__(self):
self._root = ET.Element(ns('records'), nsmap=NSMAP)

def add(self, person):
record = ET.SubElement(self._root, ns('record'), nsmap=NSMAP)
add_child(record, 'field', person['MIT_ID'], name='[Proprietary_ID]')
add_child(record, 'field', person['KRB_NAME'], name='[Username]')

def bytes(self):
return ET.tostring(self._root, encoding="UTF-8")
6 changes: 4 additions & 2 deletions carbon/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

import click

from carbon import engine, people
from carbon import engine, people, PersonFeed


@click.group()
Expand All @@ -15,5 +15,7 @@ def main():
@click.option('--db', default='sqlite:///carbon.db')
def load(db):
engine.configure(db)
feed = PersonFeed()
for person in people():
click.echo(person)
feed.add(person)
click.echo(feed.bytes())
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
click==5.1
lxml==3.5.0
SQLAlchemy==1.0.9
wheel==0.24.0
8 changes: 7 additions & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import absolute_import
import os

from lxml.builder import ElementMaker
import pytest

from carbon.db import engine, session, metadata, persons
Expand All @@ -23,11 +24,16 @@ def app_init():
def load_data():
with session() as s:
s.execute(persons.delete())
with session() as s:
s.execute(persons.insert(), [
{'MIT_ID': '123456', 'KRB_NAME': 'foobar'},
{'MIT_ID': '098754', 'KRB_NAME': 'foobaz'}
])
yield
with session() as s:
s.execute(persons.delete())


@pytest.fixture
def E():
return ElementMaker(namespace='http://www.symplectic.co.uk/hrimporter',
nsmap={None: 'http://www.symplectic.co.uk/hrimporter'})
28 changes: 28 additions & 0 deletions tests/test_app.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*-
from __future__ import absolute_import

from lxml import etree as ET
import pytest

from carbon import people
from carbon.app import PersonFeed, ns, NSMAP, add_child


pytestmark = pytest.mark.usefixtures('load_data')
Expand All @@ -15,3 +17,29 @@ def test_people_generates_people():
assert person['KRB_NAME'] == 'foobar'
person = next(peeps)
assert person['KRB_NAME'] == 'foobaz'


def test_add_child_adds_child_element(E):
xml = E.records(
E.record('foobar', {'baz': 'bazbar'})
)
e = ET.Element(ns('records'), nsmap=NSMAP)
add_child(e, 'record', 'foobar', baz='bazbar')
assert ET.tostring(e) == ET.tostring(xml)


def test_person_feed_uses_namespace():
p = PersonFeed()
assert p._root.tag == "{http://www.symplectic.co.uk/hrimporter}records"


def test_person_feed_adds_person(E):
xml = E.records(
E.record(
E.field('1234', {'name': '[Proprietary_ID]'}),
E.field('foobar', {'name': '[Username]'})
)
)
p = PersonFeed()
p.add({'MIT_ID': '1234', 'KRB_NAME': 'foobar'})
assert p.bytes() == ET.tostring(xml)
15 changes: 13 additions & 2 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import absolute_import

from click.testing import CliRunner
from lxml import etree as ET
import pytest

from carbon.cli import main
Expand All @@ -15,8 +16,18 @@ def runner():
return CliRunner()


def test_load_returns_people(runner):
def test_load_returns_people(runner, E):
xml = E.records(
E.record(
E.field('123456', name='[Proprietary_ID]'),
E.field('foobar', name='[Username]')
),
E.record(
E.field('098754', name='[Proprietary_ID]'),
E.field('foobaz', name='[Username]')
)
)
res = runner.invoke(main, ['load', '--db',
'sqlite:///tests/db/test.db'])
assert res.exit_code == 0
assert 'foobar' in res.output
assert res.output.encode('utf-8') == ET.tostring(xml) + b'\n'