def setUp(self):
        """ Setup mock dynamodb table and base configuration"""

        # base event config
        self.event = {
            "identity": {
                "username": "******"
            },
            "info": {},
            "arguments": {}
        }

        # dynamodb table
        self.dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
        self.table = self.dynamodb.create_table(TableName='scrumnest-dev',
                                                KeySchema=[{
                                                    'AttributeName': 'nestId',
                                                    'KeyType': 'HASH'
                                                }, {
                                                    'AttributeName':
                                                    'nestComponent',
                                                    'KeyType': 'RANGE'
                                                }],
                                                AttributeDefinitions=[{
                                                    'AttributeName':
                                                    'nestId',
                                                    'AttributeType':
                                                    'S'
                                                }, {
                                                    'AttributeName':
                                                    'nestComponent',
                                                    'AttributeType':
                                                    'S'
                                                }],
                                                ProvisionedThroughput={
                                                    'ReadCapacityUnits': 1,
                                                    'WriteCapacityUnits': 1
                                                })
        self.table.meta.client.get_waiter('table_exists').wait(
            TableName='scrumnest-dev')

        self.nest = Nest('abc123',
                         'NEST',
                         name='Test Nest',
                         owner='test_admin',
                         users=[{
                             'username': '******',
                             'email': '*****@*****.**'
                         }, {
                             'username': '******',
                             'email': '*****@*****.**'
                         }])
        self.nest.save()

        self.story1 = Story('abc123',
                            'STORY.123',
                            title='test story 1',
                            owner='test_admin')
        self.story1.save()
def create_story(event):
    # get nest so we know it exists first
    nest = Nest.get(event["arguments"]["nestId"], 'NEST')

    story = Story(event["arguments"]["nestId"],
                  f'STORY.{ulid.new().int >> 64}',
                  title=event["arguments"]["title"],
                  description=event["arguments"].get("descritpion", ''),
                  owner=event["arguments"].get("owner")
                  or (event["identity"] or {}).get("username"),
                  status=event["arguments"].get("status", "TODO") or "TODO",
                  sprint=event["arguments"].get("sprint", -1) or -1)
    story.save()

    return nest.to_dict()  # Return Nest for UI simplification
def update_story(event):
    nest_id = event["arguments"].pop('nestId')
    story_id = event["arguments"].pop('storyId')
    story = Story.get(nest_id, f"STORY.{story_id}")

    # handle comments first because they don't line up with model
    if event["arguments"].get('comment'):
        comment = Comment(
            username=(event["identity"] or {}).get("username", ""),
            content=event["arguments"].pop('comment'),
            createdAt=datetime.now().replace(tzinfo=dateutil.tz.gettz()),
        )
        story.comments.insert(0, comment)

    dateToBeCompleted = event["arguments"].get("dateToBeCompleted")

    # Parse string to datetime obj
    if dateToBeCompleted:
        event["arguments"]["dateToBeCompleted"] = datetime.strptime(
            dateToBeCompleted, '%Y-%m-%d')

    # Set parameters
    for arg, value in event["arguments"].items():
        if value:
            setattr(story, arg, value)

    story.save()

    return Nest.get(nest_id,
                    "NEST").to_dict()  # Return Nest for UI simplification
def delete_story(event):
    nest_id = event["arguments"].pop('nestId')
    story_id = event["arguments"].pop('storyId')

    story = Story.get(nest_id, f"STORY.{story_id}")
    story.delete()

    return Nest.get(nest_id,
                    "NEST").to_dict()  # Return Nest for UI simplification
def add_story_attachment(event):
    # get story so we know it exists first
    story = Story.get(event["arguments"]["nestId"],
                      f"STORY.{event['arguments']['storyId']}")
    new_attachment = Attachment(name=event["arguments"]["name"],
                                key=event["arguments"]["key"])
    story.attachments.append(new_attachment)
    story.save()

    return story.to_dict()
def add_comment(event):
    # get story so we know it exists first
    story = Story.get(event["arguments"]["nestId"],
                      f"STORY.{event['arguments']['storyId']}")

    comment_data = event["arguments"].pop('comment')

    comment = Comment(
        username=(event["identity"] or {}).get("username", ""),
        content=comment_data,
        createdAt=datetime.now().replace(tzinfo=dateutil.tz.gettz()),
    )

    story.comments.insert(0, comment)
    story.save()

    return story.to_dict()
def delete_story_attachment(event):
    # get story so we know it exists first
    story = Story.get(event["arguments"]["nestId"],
                      f"STORY.{event['arguments']['storyId']}")
    attachment_key = event["arguments"]["key"]

    attachments = story.attachments

    for i, attachment in enumerate(attachments):
        if attachment["key"] == attachment_key:
            attachments.pop(i)
            break

    story.attachments = attachments
    story.save()

    return story.to_dict()