diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 797276e8a3aec0ead1d0514e4d26ae46abb7ca35..15aa90907fc51bd7a34d6d44486459b9547cd85b 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,29 +2,21 @@
 image: python:3.6
 
 stages:
-  #- test
+  - test
   - release
 
-#test:
-#  stage: test
-#  script:
-#    - echo 'Make your tests here !'
-#  except:
-#    - master
-#  tags:
-#    - sib
+include:
+  - project: 'infra/platform'
+    ref: master
+    file: '/templates/python.ci.yml'
 
-publish:
-  stage: release
-  before_script:
-    - pip install python-semantic-release~=5.0 sib-commit-parser~=0.3
-    - git config user.name "${GITLAB_USER_NAME}"
-    - git config user.email "${GITLAB_USER_EMAIL}"
-    - git remote set-url origin "https://gitlab-ci-token:${GL_TOKEN}@${CI_SERVER_HOST}/${CI_PROJECT_PATH}.git"
-    - git fetch --tags
+test:
+  stage: test
   script:
-    - semantic-release publish
-  only:
+    - pip install .[dev]
+    - python -m unittest coopstarter_data.tests.runner
+  except:
     - master
+    - tags
   tags:
-    - deploy
+    - test
diff --git a/coopstarter_data/filters.py b/coopstarter_data/filters.py
new file mode 100644
index 0000000000000000000000000000000000000000..18937d81350f77efcc68a49a7f2e4a51e9f1c122
--- /dev/null
+++ b/coopstarter_data/filters.py
@@ -0,0 +1,11 @@
+from rest_framework.filters import BaseFilterBackend
+
+
+class ValidatedResourcesByStepFilterBackend(BaseFilterBackend):
+    def filter_queryset(self, request, queryset, view):
+        return queryset.filter(steps__in=view.kwargs['id'], review__status='validated')
+
+
+class PendingResourceFilterBackend(BaseFilterBackend):
+    def filter_queryset(self, request, queryset, view):
+        return queryset.filter(review__status='pending').exclude(submitter__urlid=request.user.urlid)
diff --git a/coopstarter_data/models.py b/coopstarter_data/models.py
index bebf8187f7a46e246c1ff76fafde47e46e832e59..88ffd21a80aae30294d6069daa0f4c0900b6a159 100644
--- a/coopstarter_data/models.py
+++ b/coopstarter_data/models.py
@@ -373,7 +373,7 @@ def update_review(sender, instance, created, **kwargs):
         return False
 
     if not created:
-        if instance.resource:
+        if getattr(settings, 'UPDATE_REVIEW', True) and instance.resource is not None:
             resource = instance.resource
             if instance.status == 'validated':
                 subject = 'The resource you submitted has been validated !'
diff --git a/coopstarter_data/permissions.py b/coopstarter_data/permissions.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f6bb76ff1244ccff5bf07d6eb99e039faa0df08
--- /dev/null
+++ b/coopstarter_data/permissions.py
@@ -0,0 +1,14 @@
+from djangoldp.permissions import LDPPermissions
+
+
+class PendingResourcePermissions(LDPPermissions):
+    anonymous_perms = []
+    authenticated_perms = ['view', 'add', 'delete', 'change']
+
+    def has_permission(self, request, view):
+        if request.method == 'OPTIONS':
+            return True
+
+        if request.user.is_anonymous:
+            return False
+        return True
diff --git a/coopstarter_data/tests/__init__.py b/coopstarter_data/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/coopstarter_data/tests/__pycache__/__init__.cpython-36.pyc b/coopstarter_data/tests/__pycache__/__init__.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6b183c313e8545070cee421c2413ae33851b6810
Binary files /dev/null and b/coopstarter_data/tests/__pycache__/__init__.cpython-36.pyc differ
diff --git a/coopstarter_data/tests/__pycache__/models.cpython-36.pyc b/coopstarter_data/tests/__pycache__/models.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c7fe8317744881adf2ba038a7f520b08bb329115
Binary files /dev/null and b/coopstarter_data/tests/__pycache__/models.cpython-36.pyc differ
diff --git a/coopstarter_data/tests/__pycache__/runner.cpython-36.pyc b/coopstarter_data/tests/__pycache__/runner.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7b535aaff5ad529b9700d7f36d321b1e7ddb7eff
Binary files /dev/null and b/coopstarter_data/tests/__pycache__/runner.cpython-36.pyc differ
diff --git a/coopstarter_data/tests/__pycache__/tests_get.cpython-36.pyc b/coopstarter_data/tests/__pycache__/tests_get.cpython-36.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e5e952653a82c30b0fb2e1d4410f449a0d326c31
Binary files /dev/null and b/coopstarter_data/tests/__pycache__/tests_get.cpython-36.pyc differ
diff --git a/coopstarter_data/tests/models.py b/coopstarter_data/tests/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..0f0400b1817724563f8a447476410a4c14231ce5
--- /dev/null
+++ b/coopstarter_data/tests/models.py
@@ -0,0 +1,13 @@
+from django.contrib.auth.models import AbstractUser
+
+from djangoldp.models import Model
+
+
+class User(AbstractUser, Model):
+
+    class Meta(AbstractUser.Meta, Model.Meta):
+        serializer_fields = ['@id', 'username', 'first_name', 'last_name', 'email', 'resources']
+        nested_fields = ['resources']
+        anonymous_perms = ['view', 'add']
+        authenticated_perms = ['inherit', 'change']
+        owner_perms = ['inherit']
diff --git a/coopstarter_data/tests/runner.py b/coopstarter_data/tests/runner.py
new file mode 100644
index 0000000000000000000000000000000000000000..5b98333f1f3540092d8fe38f80b044773eefc735
--- /dev/null
+++ b/coopstarter_data/tests/runner.py
@@ -0,0 +1,46 @@
+import sys
+
+import django
+from django.conf import settings
+from djangoldp.tests import settings_default
+
+settings.configure(default_settings=settings_default,
+                   DJANGOLDP_PACKAGES=['djangoldp_conversation', 'djangoldp_like', 'coopstarter_data',
+                                       'coopstarter_data.tests', ],
+                   INSTALLED_APPS=('django.contrib.auth',
+                                   'django.contrib.contenttypes',
+                                   'django.contrib.sessions',
+                                   'django.contrib.admin',
+                                   'django.contrib.messages',
+                                   'django.contrib.staticfiles',
+                                   'guardian',
+                                   'djangoldp_conversation',
+                                   'djangoldp_like',
+                                   'coopstarter_data',
+                                   'coopstarter_data.tests',
+                                   'djangoldp',
+                                   ),
+                   SITE_URL='http://happy-dev.fr',
+                   BASE_URL='http://happy-dev.fr',
+                   REST_FRAMEWORK = {
+                       'DEFAULT_PAGINATION_CLASS': 'djangoldp.pagination.LDPPagination',
+                       'PAGE_SIZE': 5
+                   },
+                   SEND_BACKLINKS=False,
+                   JABBER_DEFAULT_HOST=None,
+                   PERMISSIONS_CACHE=False,
+                   ANONYMOUS_USER_NAME=None,
+                   SERIALIZER_CACHE=False,
+                   UPDATE_REVIEW=False
+                   )
+
+django.setup()
+from django.test.runner import DiscoverRunner
+
+test_runner = DiscoverRunner(verbosity=1)
+
+failures = test_runner.run_tests([
+    'coopstarter_data.tests.tests_get',
+])
+if failures:
+    sys.exit(failures)
diff --git a/coopstarter_data/tests/tests_get.py b/coopstarter_data/tests/tests_get.py
new file mode 100644
index 0000000000000000000000000000000000000000..a0cbbd1f29a464328bea258a0e4ab2fa757988d6
--- /dev/null
+++ b/coopstarter_data/tests/tests_get.py
@@ -0,0 +1,115 @@
+import uuid
+import json
+from datetime import datetime, timedelta
+
+from djangoldp.permissions import LDPPermissions
+
+from djangoldp.serializers import LDListMixin, LDPSerializer
+from rest_framework.test import APITestCase, APIClient
+
+from coopstarter_data.models import Resource, Review, Step
+from coopstarter_data.tests.models import User
+
+
+class GETTestCase(APITestCase):
+    def setUp(self):
+        self.client = APIClient()
+        LDListMixin.to_representation_cache.reset()
+        LDPSerializer.to_representation_cache.reset()
+        LDPPermissions.invalidate_cache()
+
+    def setUpLoggedInUser(self):
+        self.user = User(email='test@mactest.co.uk', first_name='Test', last_name='Mactest', username='test',
+                         password='glass onion')
+        self.user.save()
+        self.client.force_authenticate(user=self.user)
+
+    def setUpResource(self):
+        self.resource = self._get_resource(name='Test')
+
+    def _get_attached_review(self, resource=None, **extra):
+        if resource is None:
+            resource = self.resource
+
+        review = Review.objects.create(**extra)
+        resource.review = review
+        resource.save()
+        return review
+
+    def _get_resource(self, **extra):
+        return Resource.objects.create(**extra)
+
+    def _get_step(self):
+        return Step.objects.create(name='Test')
+
+    def test_list_resources_nested_serializer(self):
+        self.setUpLoggedInUser()
+        self.resource = self._get_resource(name='Test', submitter=self.user)
+
+        response = self.client.get('/users/1/')
+        self.assertIn('resources', response.data)
+        self.assertEqual(len(response.data['resources']['ldp:contains']), 1)
+        self.assertEqual(response.data['resources']['ldp:contains'][0]['@id'], self.resource.urlid)
+
+    def test_list_resources_nested_viewset(self):
+        self.setUpLoggedInUser()
+        self.resource = self._get_resource(name='Test', submitter=self.user)
+
+        response = self.client.get('/users/1/resources/')
+        self.assertIn('ldp:contains', response.data)
+        self.assertEqual(len(response.data['ldp:contains']), 1)
+        self.assertEqual(response.data['ldp:contains'][0]['@id'], self.resource.urlid)
+
+    def test_list_pending_resources(self):
+        self.setUpLoggedInUser()
+        # one local resource which nobody submitted
+        self.setUpResource()
+        self._get_attached_review(resource=self.resource, status='pending')
+
+        # two external resources (should not be returned)
+        external_resource_backlink = self._get_resource(name='Test2', is_backlink=True, urlid='https://external.com/resource/1/')
+        self._get_attached_review(resource=external_resource_backlink, status='pending')
+        external_resource_non_backlink = self._get_resource(name='Test3', is_backlink=False, urlid='https://external.com/resource/2/')
+        self._get_attached_review(resource=external_resource_non_backlink, status='pending')
+
+        # one local resource which I did submit (should not be returned)
+        resource = self._get_resource(name='Test4', submitter=self.user)
+        self._get_attached_review(resource=resource, status='pending')
+
+        response = self.client.get('/resources/pending/')
+        self.assertIn('ldp:contains', response.data)
+        self.assertEqual(len(response.data['ldp:contains']), 1)
+        self.assertEqual(response.data['ldp:contains'][0]['name'], 'Test')
+
+    def test_list_pending_resources_anonymous(self):
+        self.setUpResource()
+        self._get_attached_review(resource=self.resource, status='pending')
+
+        response = self.client.get('/resources/pending/')
+        self.assertEqual(response.status_code, 403)
+
+    def test_list_pending_resources_options_anonymous(self):
+        self.setUpResource()
+        self._get_attached_review(resource=self.resource, status='pending')
+
+        response = self.client.options('/resources/pending/')
+        self.assertEqual(response.status_code, 200)
+
+    def test_list_validated_resources(self):
+        step = self._get_step()
+        self.setUpResource()
+        self._get_attached_review(resource=self.resource, status='validated')
+        self.resource.steps.add(step)
+
+        pending_resource = self._get_resource()
+        self._get_attached_review(resource=pending_resource, status='pending')
+        pending_resource.steps.add(step)
+
+        external_resource = self._get_resource(urlid='https://external.com/resource/1/')
+        self._get_attached_review(resource=external_resource, status='validated')
+        external_resource.steps.add(step)
+
+        response = self.client.get('/steps/{}/resources/validated/'.format(step.pk))
+        self.assertIn('ldp:contains', response.data)
+        self.assertEqual(len(response.data['ldp:contains']), 1)
+        self.assertEqual(response.data['ldp:contains'][0]['name'], 'Test')
diff --git a/coopstarter_data/views.py b/coopstarter_data/views.py
index 44717bae2f7553034ca85a994ec06e70a7ea66f3..ea8b1ff0448bfcbb723c61af29ecb0e5e727021b 100644
--- a/coopstarter_data/views.py
+++ b/coopstarter_data/views.py
@@ -1,31 +1,16 @@
-from djangoldp.views import LDPViewSet
-from .models import Resource, Step
+from djangoldp.filters import LocalObjectFilterBackend
+from coopstarter_data.models import Resource
+from coopstarter_data.filters import PendingResourceFilterBackend, ValidatedResourcesByStepFilterBackend
+from coopstarter_data.permissions import PendingResourcePermissions
 from djangoldp_i18n.views import I18nLDPViewSet
 
-class ValidatedResourcesByStepViewSet(I18nLDPViewSet):
-  model = Resource
 
-  def get_queryset(self, *args, **kwargs):
-    step_id = self.kwargs['id']
-    # if hasattr(self.request.user, 'contributor_profile'):
-    #   target='contributor'
-    # elif hasattr(self.request.user, 'searcher_profile'):
-    #   target='searcher'
-    # else:
-    #   target='public'
+class ValidatedResourcesByStepViewSet(I18nLDPViewSet):
+    model = Resource
+    filter_backends = [ValidatedResourcesByStepFilterBackend, LocalObjectFilterBackend]
 
-    # Additional filter criteria: , target__value=target
-    return super().get_queryset(*args, **kwargs)\
-          .filter(steps__in=step_id, review__status='validated')\
-          .exclude(is_backlink=True)
 
 class PendingResourcesViewSet(I18nLDPViewSet):
-  model = Resource
-
-  def get_queryset(self, *args, **kwargs):
-    # Deactivating those additional filters for now.
-    # , language__in=self.request.user.contributor_profile.languages.all(), fields__in=self.request.user.contributor_profile.fields.all()
-    return super().get_queryset(*args, **kwargs)\
-          .filter(review__status='pending')\
-          .exclude(submitter__username=self.request.user.username)\
-          .exclude(is_backlink=True)
\ No newline at end of file
+    model = Resource
+    filter_backends = [PendingResourceFilterBackend, LocalObjectFilterBackend]
+    permission_classes = [PendingResourcePermissions]
diff --git a/setup.cfg b/setup.cfg
index 245ae45223a270f5e90a3bc53c6a5c8d5e2fac73..94765136fc3b104282438e9784dde933bed8a248 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -14,7 +14,15 @@ classifiers =
 [options]
 packages = find:
 install_requires =
-    djangoldp~=0.5
+    djangoldp>=1.4
+    djangoldp_account>=1.0.0
+    djangoldp_conversation>=1.0.0
+    djangoldp_like>=0.0.1
+    djangoldp_i18n>=1.0.0
+    
+[options.extras_require]
+dev =
+    factory_boy>=2.11.0
 
 [semantic_release]
 version_source = tag
diff --git a/setup.py b/setup.py
index 6b76fe5111ad4f555c279456efbc252bd4024ac9..de90db022d444a5702afc118f35d51a2ebb19961 100644
--- a/setup.py
+++ b/setup.py
@@ -4,6 +4,5 @@
 
 from setuptools import setup
 setup(
-    include_package_data=True,
-    install_requires=["Pillow"]
+    include_package_data=True
 )