diff --git a/config/default.py b/config/default.py
index fa1a1a14..049863ff 100644
--- a/config/default.py
+++ b/config/default.py
@@ -79,11 +79,11 @@ GITHUB_REPO = environ.get('GITHUB_REPO', None)
TARGET_BRANCH = environ.get('TARGET_BRANCH', None)
# Git settings, used by git_service
-# The above Github settings--used in file_service, will likely be deprecated
-# You can override these settings in instance/config
-GIT_REMOTE_PATH = environ.get('GIT_REMOTE_PATH', None)
-GIT_BRANCH = environ.get('GIT_BRANCH', None)
-GIT_MERGE_BRANCH = environ.get('GIT_MERGE_BRANCH', None) # Developers can set this to 'all' in instance.config
+# Among other things, we use these to build a remote URL like https://username:password@host/path.git
+GIT_REMOTE_SERVER = environ.get('GIT_REMOTE_SERVER', None) # example: 'github.com'
+GIT_REMOTE_PATH = environ.get('GIT_REMOTE_PATH', None) # example: 'sartography/crconnect-workflow-specs
+GIT_BRANCH = environ.get('GIT_BRANCH', None) # example: 'main'
+GIT_MERGE_BRANCH = environ.get('GIT_MERGE_BRANCH', None) # Example: 'staging'
# Email configuration
DEFAULT_SENDER = 'uvacrconnect@virginia.edu'
diff --git a/crc/api.yml b/crc/api.yml
index 0102b0e0..710a7c65 100755
--- a/crc/api.yml
+++ b/crc/api.yml
@@ -2381,10 +2381,9 @@ components:
merge_branch:
type: string
example: staging
-# status:
-# type: string
-# example: staging
changes:
type: array
+ example: ['file_1.txt', 'file_2.txt']
untracked:
type: array
+ example: ['a_file.txt', 'b_file.txt']
diff --git a/crc/scripts/get_spec_from_id.py b/crc/scripts/get_spec_from_id.py
new file mode 100644
index 00000000..915d709d
--- /dev/null
+++ b/crc/scripts/get_spec_from_id.py
@@ -0,0 +1,22 @@
+from crc.api.common import ApiError
+from crc.models.workflow import WorkflowSpecInfoSchema
+from crc.scripts.script import Script
+from crc.services.workflow_spec_service import WorkflowSpecService
+
+
+class ScriptTemplate(Script):
+
+ def get_description(self):
+ return """Get workflow spec information from a workflow spec id"""
+
+ def do_task_validate_only(self, task, study_id, workflow_id, *args, **kwargs):
+ return self.do_task(task, study_id, workflow_id, *args, **kwargs)
+
+ def do_task(self, task, study_id, workflow_id, *args, **kwargs):
+ if len(args) < 1:
+ raise ApiError(code='missing_spec_id',
+ message='The get_spec_from_id script requires a spec_id.')
+ spec_id = args[0]
+ workflow_spec = WorkflowSpecService().get_spec(spec_id)
+
+ return WorkflowSpecInfoSchema().dump(workflow_spec)
diff --git a/crc/services/file_system_service.py b/crc/services/file_system_service.py
index 2af58dfb..b4e8b373 100644
--- a/crc/services/file_system_service.py
+++ b/crc/services/file_system_service.py
@@ -108,8 +108,10 @@ class FileSystemService(object):
items = os.scandir(file_path)
for item in items:
if item.is_file():
+ if item.name.startswith('.'):
+ continue # Ignore hidden files
if item.name == FileSystemService.WF_JSON_FILE:
- continue # Ignore the json files.
+ continue # Ignore the json files.
if file_name is not None and item.name != file_name:
continue
file = FileSystemService.to_file_object_from_dir_entry(item)
diff --git a/crc/services/git_service.py b/crc/services/git_service.py
index 38786bdd..d0672a21 100644
--- a/crc/services/git_service.py
+++ b/crc/services/git_service.py
@@ -29,11 +29,10 @@ class GitService(object):
@staticmethod
def get_remote_url(remote_path):
- # we use github
- # Note that the 'password' is a token generated by github, not the site password
+ host = app.config['GIT_REMOTE_SERVER']
username = app.config["GIT_USER_NAME"]
password = app.config["GIT_USER_PASS"]
- remote_url = f"https://{username}:{password}@github.com/{remote_path}.git"
+ remote_url = f"https://{username}:{password}@{host}/{remote_path}.git"
return remote_url
@staticmethod
diff --git a/crc/services/user_file_service.py b/crc/services/user_file_service.py
index da8e32fa..10e923d2 100644
--- a/crc/services/user_file_service.py
+++ b/crc/services/user_file_service.py
@@ -195,66 +195,6 @@ class UserFileService(object):
app.logger.info("Failed to delete file, so archiving it instead. %i, due to %s" % (file_id, str(ie)))
raise ApiError('Delete Failed', "Unable to delete file. ")
- @staticmethod
- def get_repo_branches():
- gh_token = app.config['GITHUB_TOKEN']
- github_repo = app.config['GITHUB_REPO']
- _github = Github(gh_token)
- repo = _github.get_user().get_repo(github_repo)
- branches = [branch.name for branch in repo.get_branches()]
- return branches
-
- @staticmethod
- def update_from_github(file_ids, source_target=GithubObject.NotSet):
- gh_token = app.config['GITHUB_TOKEN']
- github_repo = app.config['GITHUB_REPO']
- _github = Github(gh_token)
- repo = _github.get_user().get_repo(github_repo)
-
- for file_id in file_ids:
- file_data_model = FileDataModel.query.filter_by(
- file_model_id=file_id
- ).order_by(
- desc(FileDataModel.version)
- ).first()
- try:
- repo_file = repo.get_contents(file_data_model.file_model.name, ref=source_target)
- except UnknownObjectException:
- return {'error': 'Attempted to update from repository but file was not present'}
- else:
- file_data_model.data = repo_file.decoded_content
- session.add(file_data_model)
- session.commit()
-
- @staticmethod
- def publish_to_github(file_ids):
- target_branch = app.config['TARGET_BRANCH'] if app.config['TARGET_BRANCH'] else GithubObject.NotSet
- gh_token = app.config['GITHUB_TOKEN']
- github_repo = app.config['GITHUB_REPO']
- _github = Github(gh_token)
- repo = _github.get_user().get_repo(github_repo)
- for file_id in file_ids:
- file_data_model = FileDataModel.query.filter_by(file_model_id=file_id).first()
- try:
- repo_file = repo.get_contents(file_data_model.file_model.name, ref=target_branch)
- except UnknownObjectException:
- repo.create_file(
- path=file_data_model.file_model.name,
- message=f'Creating {file_data_model.file_model.name}',
- content=file_data_model.data,
- branch=target_branch
- )
- return {'created': True}
- else:
- updated = repo.update_file(
- path=repo_file.path,
- message=f'Updating {file_data_model.file_model.name}',
- content=file_data_model.data + b'brah-model',
- sha=repo_file.sha,
- branch=target_branch
- )
- return {'updated': True}
-
@staticmethod
def dmn_from_spreadsheet(ss_data):
diff --git a/crc/services/workflow_service.py b/crc/services/workflow_service.py
index 3872c0e8..8fa924fc 100755
--- a/crc/services/workflow_service.py
+++ b/crc/services/workflow_service.py
@@ -541,6 +541,8 @@ class WorkflowService(object):
return FileSchema().dump(file)
elif field.type == 'files':
return random.randrange(1, 100)
+ elif field.type == 'date':
+ return datetime.utcnow()
else:
return WorkflowService._random_string()
diff --git a/tests/data/date_validation/date_validation.bpmn b/tests/data/date_validation/date_validation.bpmn
new file mode 100644
index 00000000..8cf29260
--- /dev/null
+++ b/tests/data/date_validation/date_validation.bpmn
@@ -0,0 +1,82 @@
+
+
+
+
+ Flow_09e6w2a
+
+
+
+
+
+ Flow_19hbirj
+
+
+
+
+
+
+
+
+
+
+
+
+ Flow_09e6w2a
+ Flow_0cbbsi7
+
+
+ Flow_0cbbsi7
+ Flow_0dvxkh6
+ delta1 = timedelta(hours=2)
+format = '%Y-%m-%dT%H:%M:%S.%fZ'
+the_date = datetime.datetime.strptime(a_date, format)
+modified_date = the_date + delta1
+del(delta1)
+
+
+ # Dates
+
+## A Date
+{{ a_date }}
+
+
+ Flow_0dvxkh6
+ Flow_19hbirj
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/data/spec_from_id/spec_from_id.bpmn b/tests/data/spec_from_id/spec_from_id.bpmn
new file mode 100644
index 00000000..2c104af1
--- /dev/null
+++ b/tests/data/spec_from_id/spec_from_id.bpmn
@@ -0,0 +1,75 @@
+
+
+
+
+ Flow_08i8lxh
+
+
+
+
+
+ Flow_0saprky
+
+
+
+
+
+
+
+
+
+
+
+
+ Flow_08i8lxh
+ Flow_1fhu6em
+
+
+ Flow_1fhu6em
+ Flow_06e4nx2
+ spec = get_spec_from_id(spec_id)
+
+
+ ## Spec
+{{ spec }}
+
+ Flow_06e4nx2
+ Flow_0saprky
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/scripts/test_get_spec_from_id.py b/tests/scripts/test_get_spec_from_id.py
new file mode 100644
index 00000000..3cb7c3d9
--- /dev/null
+++ b/tests/scripts/test_get_spec_from_id.py
@@ -0,0 +1,15 @@
+from tests.base_test import BaseTest
+
+
+class TestSpecFromWorkflowID(BaseTest):
+
+ def test_get_spec_from_workflow_id(self):
+ workflow = self.create_workflow('spec_from_id')
+ workflow_spec_id = workflow.workflow_spec_id
+ workflow_api = self.get_workflow_api(workflow)
+ task = workflow_api.next_task
+ workflow_api = self.complete_form(workflow, task, {'spec_id': workflow_spec_id})
+ task = workflow_api.next_task
+
+ self.assertEqual('spec_from_id', task.data['spec']['id'])
+ self.assertEqual('spec_from_id', task.data['spec']['display_name'])
diff --git a/tests/test_git_service.py b/tests/test_git_service.py
index 14549a63..5fd11a76 100644
--- a/tests/test_git_service.py
+++ b/tests/test_git_service.py
@@ -1,5 +1,6 @@
from tests.base_test import BaseTest
+from crc import app
from crc.services.git_service import GitService
from unittest.mock import patch, Mock, call
@@ -57,6 +58,10 @@ class TestGitService(BaseTest):
self.assertIn(call.index.commit('This is my comment'), method_calls)
self.assertIn(call.remotes.origin.push(), method_calls)
- # def test_pull_from_remote(self):
- # result = GitService.pull_from_remote()
- # print(result)
+ def test_get_remote_url(self):
+ app.config['GIT_REMOTE_SERVER'] = 'test_server.com'
+ app.config['GIT_USER_NAME'] = 'test_username'
+ app.config['GIT_USER_PASS'] = 'test_pass'
+
+ result = GitService.get_remote_url('my_test_path')
+ self.assertEqual('https://test_username:test_pass@test_server.com/my_test_path.git', result)
diff --git a/tests/workflow/test_workflow_date_field_validation.py b/tests/workflow/test_workflow_date_field_validation.py
new file mode 100644
index 00000000..8f468cd6
--- /dev/null
+++ b/tests/workflow/test_workflow_date_field_validation.py
@@ -0,0 +1,12 @@
+from tests.base_test import BaseTest
+
+
+class TestDateValidation(BaseTest):
+
+ def test_date_validation(self):
+
+ """We were not instantiating date fields correctly during validation.
+ This is a simple test to make sure we seed an actual date in date fields instead of a random string."""
+ spec_model = self.load_test_spec('date_validation')
+ rv = self.app.get('/v1.0/workflow-specification/%s/validate' % spec_model.id, headers=self.logged_in_headers())
+ self.assertEqual([], rv.json)