def setUp(self):
        delete_sample_user_states()
        self.user_state_schema = create_user_state_config(
            default_class_config())
        self.user_states = create_sample_user_states(
            UserState, get_region_model(), get_project_model(),
            get_location_schema()['model_class'],
            get_search_location_schema()['model_class'])
        # Gather all unique sample users
        self.users = list(
            set(R.map(lambda user_state: user_state.user, self.user_states)))
        self.client = client_for_testing(schema(), self.users[0])
        # Gather all unique sample regions
        self.regions = R.compose(
            # Forth Resolve persisted Regions
            R.map(lambda id: get_region_model().objects.get(id=id)),
            # Third make ids unique
            lambda ids: list(set(ids)),
            # Second map each to the region id
            R.map(R.item_str_path('region.id')),
            # First flat map the user regions of all user_states
            R.chain(lambda user_state: R.item_str_path(
                'data.userRegions', user_state.__dict__)))(self.user_states)
        # Gather all unique sample projects
        self.projects = R.compose(
            # Forth Resolve persisted Projects
            R.map(lambda id: get_project_model().objects.get(id=id)),
            # Third make ids unique
            lambda ids: list(set(ids)),
            # Second map each to the project id
            R.map(R.item_str_path('project.id')),
            # First flat map the user regions of all user_states
            R.chain(lambda user_state: R.item_str_path(
                'data.userProjects', user_state.__dict__)))(self.user_states)
        self.locations = create_local_sample_locations(
            get_location_schema()['model_class'])

        def extract_search_location_ids(user_regions):
            return R.map(
                R.item_str_path('searchLocation.id'),
                R.chain(R.item_str_path('userSearch.userSearchLocations'),
                        user_regions))

        # Gather all unique searches locations from userRegions.
        # user searches could also be in userProjects, but we'll ignore that
        self.search_locations = R.compose(
            # Forth Resolve persisted UserSearches
            lambda ids: R.map(
                lambda id: get_search_location_schema()['model_class'].objects.
                get(id=id), ids),
            # Third make ids unique
            lambda ids: list(set(ids)),
            # Chain to a flat list of user search location ids
            lambda user_regions: extract_search_location_ids(user_regions),
            # First flat map the user regions of all user_states
            R.chain(lambda user_state: R.item_str_path(
                'data.userRegions', user_state.__dict__)))(self.user_states)
        # Can be set by inheritors
        self.additional_user_scope_data = {}
Beispiel #2
0
 def test_create(self):
     values = dict(username="******", firstName='T', lastName='Rex',
                   password=make_password("rrrrhhh", salt='not_random'))
     result = graphql_update_or_create_user(self.client, values)
     assert_no_errors(result)
     # look at the users added and omit the non-determinant dateJoined
     assert R.item_str_path('data.createUser.user', result)
     versions = Version.objects.get_for_object(get_user_model().objects.get(
         id=R.item_str_path('data.createUser.user.id', result)
     ))
     assert len(versions) == 1
Beispiel #3
0
 def test_create(self):
     result, new_result = quiz_model_mutation_create(
         self.client, graphql_update_or_create_project, 'createProject.project',
         dict(
             name='Carre',
             key='carre',
             geojson={
                 'type': 'FeatureCollection',
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                              [51.4750237087, 6.15665815596],
                              [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                     }
                 }]
             },
             data=dict(),
             locations=R.map(R.compose(R.pick(['id']), lambda l: l.__dict__), self.locations),
             user=R.pick(['id'], R.head(self.users).__dict__),
         ),
         dict(key=r'carre.+'))
     versions = Version.objects.get_for_object(get_project_model().objects.get(
         id=R.item_str_path('data.createProject.project.id', result)
     ))
     assert len(versions) == 1
Beispiel #4
0
 def test_create(self):
     result, new_result = quiz_model_mutation_create(
         self.client,
         graphql_update_or_create_location,
         'createLocation.location',
         dict(
             name='Grote Markt',
             key='groteMarkt',
             geojson={
                 'type': 'FeatureCollection',
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                              [51.4750237087, 6.15665815596],
                              [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                     }
                 }]
             },
             data=dict()
         ),
         # Second create should create a new record that matches this regex
         dict(key=r'groteMarkt.+')
     )
     versions = Version.objects.get_for_object(Location.objects.get(
         id=R.item_str_path('data.createLocation.location.id', result)
     ))
     assert len(versions) == 1
 def test_update(self):
     result, update_result = quiz_model_mutation_update(
         self.client, graphql_update_or_create_resource,
         'createResource.resource', 'updateResource.resource',
         dict(
             key='candy',
             name='Candy',
             region=dict(id=self.region.id),
             data=R.merge(
                 sample_settings,
                 dict(
                     material='Candy',
                     rawData=[
                         'Other Global Imports;Shipments, location generalized;51.309933, 3.055030;Source;22,469,843',
                         'Knauf (Danilith) BE;Waregemseweg 156-142 9790 Wortegem-Petegem, Belgium;50.864762, 3.479308;Conversion;657,245',
                         "MPRO Bruxelles;Avenue du Port 67 1000 Bruxelles, Belgium;50.867486, 4.352543;Distribution;18,632",
                         'Residential Buildings (all typologies);Everywhere in Brussels;NA;Demand;3,882,735',
                         'Duplex House Typology;Everywhere in Brussels;NA;Demand;13,544',
                         'Apartment Building Typology;Everywhere in Brussels;NA;Demand;34,643',
                         'New West Gypsum Recycling;9130 Beveren, Sint-Jansweg 9 Haven 1602, Kallo, Belgium;51.270229, 4.261048;Reconversion;87,565',
                         'Residential Buildings (all typologies);Everywhere in Brussels;NA;Sink;120,000',
                         'RecyPark South;1190 Forest, Belgium;50.810799, 4.314789;Sink;3,130',
                         'RecyPark Nord;Rue du Rupel, 1000 Bruxelles, Belgium;50.880181, 4.377136;Sink;1,162'
                     ]))), dict(key='popcorn', name='Popcorn'))
     versions = Version.objects.get_for_object(
         Resource.objects.get(id=R.item_str_path(
             'data.updateResource.resource.id', update_result)))
     assert len(versions) == 2
 def test_update(self):
     (result, update_result) = quiz_model_mutation_update(
         self.client,
         graphql_update_or_create_foo,
         'createFoo.foo',
         'updateFoo.foo',
         dict(name='Luxembourg',
              key='luxembourg',
              user=R.pick(['id'], self.admin),
              geojson=geojson,
              data=dict(example=1.1, friend=R.pick(['id'], self.user))),
         # Update the coords
         dict(
             geojson={
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type":
                         "Polygon",
                         "coordinates": [[[49.5294835476, 2.51357303225],
                                          [51.4750237087, 2.51357303225],
                                          [51.4750237087, 6.15665815596],
                                          [49.5294835476, 6.15665815596],
                                          [49.5294835476, 2.51357303225]]]
                     }
                 }]
             }))
     versions = Version.objects.get_for_object(
         Foo.objects.get(
             id=R.item_str_path('data.updateFoo.foo.id', update_result)))
     assert len(versions) == 2
    def test_update(self):
        # First add a new User
        margay = dict(username="******",
                      first_name='Upa',
                      last_name='Tree',
                      password=make_password("merowgir", salt='not_random'))
        user = create_sample_user(margay)

        # Now assign regions and persist the UserState
        sample_user_state_data = dict(
            user=dict(id=user.id),
            data=form_sample_user_state_data(
                self.regions,
                self.projects,
                dict(
                    userRegions=[
                        dict(
                            # Assign the first region
                            region=dict(
                                key=R.prop('key', R.head(self.regions))),
                            mapbox=dict(viewport=dict(
                                latitude=50.5915, longitude=2.0165, zoom=7)))
                    ],
                    userProjects=[
                        dict(
                            # Assign the first prjoect
                            project=dict(
                                key=R.prop('key', R.head(self.projects))),
                            mapbox=dict(viewport=dict(
                                latitude=50.5915, longitude=2.0165, zoom=7)))
                    ])))

        # Update the zoom of the first userRegion
        update_data = deepcopy(R.pick(['data'], sample_user_state_data))
        R.item_str_path(
            'mapbox.viewport',
            R.head(R.item_str_path('data.userRegions',
                                   (update_data))))['zoom'] = 15

        result, update_result = quiz_model_mutation_update(
            self.client, R.prop('graphql_mutation', self.user_state_schema),
            'createUserState.userState', 'updateUserState.userState',
            sample_user_state_data, update_data)
        versions = Version.objects.get_for_object(
            UserState.objects.get(id=R.item_str_path(
                'data.updateUserState.userState.id', update_result)))
        assert len(versions) == 2
Beispiel #8
0
    def test_update(self):
        values = dict(username="******", firstName='T', lastName='Rex',
                      password=make_password("rrrrhhh", salt='not_random'))
        # Here is our create
        create_result = graphql_update_or_create_user(self.client, values)

        # Unfortunately Graphene returns the ID as a string, even when its an int
        id = R.prop('id', R.item_str_path('data.createUser.user', create_result))

        # Here is our update
        result = graphql_update_or_create_user(
            self.client,
            dict(id=id, firstName='Al', lastName="Lissaurus")
        )
        assert_no_errors(result)
        assert R.item_str_path('data.updateUser.user', result)
        versions = Version.objects.get_for_object(get_user_model().objects.get(
            id=R.item_str_path('data.updateUser.user.id', result)
        ))
        assert len(versions) == 2
 def test_create(self):
     (result, new_result) = quiz_model_mutation_create(
         self.client, graphql_update_or_create_region, 'createRegion.region',
         dict(
             name='Luxembourg',
             key='luxembourg',
             geojson={
                 'type': 'FeatureCollection',
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                              [51.4750237087, 6.15665815596],
                              [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                     }
                 }]
             },
             data=dict(
                 locations=dict(
                     params=dict(
                         city='Luxembourg City'
                     )
                 ),
                 # Optional default mapbox settings for the region
                 mapbox=dict(
                     viewport=dict(
                         # Extent can replace latitude, longitude, zoom for complex cases
                         extent=dict(
                             type='FeatureCollection',
                             features=[dict(
                                 type='Feature',
                                 geometry=dict(
                                     type='Polygon',
                                     coordinates=[
                                         [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                                          [51.4750237087, 6.15665815596],
                                          [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                                 )
                             )]
                         ),
                     )
                 )
             )
         ),
         dict(key=r'luxembourg.+')
     )
     versions = Version.objects.get_for_object(Region.objects.get(
         id=R.item_str_path('data.createRegion.region.id', result)
     ))
     assert len(versions) == 1
 def test_create(self):
     (result, new_result) = quiz_model_mutation_create(
         self.client, graphql_update_or_create_foo, 'createFoo.foo',
         dict(name='Luxembourg',
              key='luxembourg',
              user=R.pick(['id'], self.admin),
              geojson=geojson,
              data=dict(example=1.1, friend=R.pick(['id'], self.user))),
         dict(key=r'luxembourg.+'))
     versions = Version.objects.get_for_object(
         Foo.objects.get(
             id=R.item_str_path('data.createFoo.foo.id', result)))
     assert len(versions) == 1
def quiz_model_mutation_update(client, graphql_update_or_create_function,
                               create_path, update_path, values,
                               update_values):
    """
        Tests an update mutation for a model by calling a create with the given values then an update
        with the given update_values (plus the create id)
    :param client: The Apollo Client
    :param graphql_update_or_create_function: The update or create mutation function for the model. Expects client and input values
    :param create_path: The path to the result of the create in the data object (e.g. createRegion.region)
    :param update_path: The path to the result of the update in the data object (e.g. updateRegion.region)
    :param values: The input values to use for the create
    :param update_values: The input values to use for the update. This can be as little as one key value
    :return:
    """
    result = graphql_update_or_create_function(client, values=values)
    assert not R.has('errors', result), R.dump_json(
        R.map(lambda e: format_error(e), R.prop('errors', result)))
    # Extract the result and map the graphql keys to match the python keys
    created = R.compose(
        lambda r: R.map_keys(lambda key: underscore(key), r),
        lambda r: R.item_str_path(f'data.{create_path}', r))(result)
    # look at the users added and omit the non-determinant dateJoined
    assert values == pick_deep(created, values)
    # Update with the id and optionally key if there is one + update_values
    update_result = graphql_update_or_create_function(
        client,
        R.merge_all([
            dict(id=created['id']),
            dict(key=created['key'])
            if R.prop_or(False, 'key', created) else {}, update_values
        ]))
    assert not R.has('errors', update_result), R.dump_json(
        R.map(lambda e: format_error(e), R.prop('errors', update_result)))
    updated = R.item_str_path(f'data.{update_path}', update_result)
    assert created['id'] == updated['id']
    assert update_values == pick_deep(update_values, updated)
    return result, update_result
Beispiel #12
0
 def test_authenticate(self):
     values = dict(username=self.user.username, password='******')
     result = graphql_token_auth_mutation(self.client, values)
     assert_no_errors(result)
     auth_token = R.item_str_path('data.tokenAuth.token', result)
     assert auth_token
     verify_result = graphql_verify_token_mutation(self.client, dict(token=auth_token))
     assert_no_errors(verify_result)
     refresh_result = graphql_refresh_token_mutation(self.client, dict(token=auth_token))
     assert_no_errors(refresh_result)
     delete_token_cookie_result = graphql_delete_token_cookie_mutation(self.client, {})
     assert_no_errors(delete_token_cookie_result)
     delete_token_cookie_result = graphql_delete_token_cookie_mutation(self.client, {})
     assert_no_errors(delete_token_cookie_result)
     delete_refresh_token_cookie_result = graphql_delete_refresh_token_cookie_mutation(self.client, {})
     assert_no_errors(delete_refresh_token_cookie_result)
 def test_create(self):
     result, _ = quiz_model_mutation_create(
         self.client, graphql_update_or_create_settings,
         'createSettings.settings',
         dict(key='mars',
              data=dict(domain='localhost',
                        api=dict(protocol='http',
                                 host='localhost',
                                 port='8008',
                                 path='/graphql/'),
                        overpass=dict(cellSize=100, sleepBetweenCalls=1000),
                        mapbox=dict(viewport={}, ))))
     versions = Version.objects.get_for_object(
         Settings.objects.get(
             id=R.item_str_path('data.createSettings.settings.id', result)))
     assert len(versions) == 1
Beispiel #14
0
 def test_update(self):
     result, update_result = quiz_model_mutation_update(
         self.client,
         graphql_update_or_create_project,
         'createProject.project',
         'updateProject.project',
         dict(
             name='Carre',
             key='carre',
             geojson={
                 'type': 'FeatureCollection',
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.4426671413, 5.67405195478], [50.1280516628, 5.67405195478],
                              [50.1280516628, 6.24275109216],
                              [49.4426671413, 6.24275109216], [49.4426671413, 5.67405195478]]]
                     }
                 }]
             },
             data=dict(),
             locations=R.map(R.compose(R.pick(['id']), lambda l: l.__dict__), self.locations),
             user=R.pick(['id'], R.head(self.users).__dict__),
         ),
         # Update the coords and limit to one location
         dict(
             geojson={
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                              [51.4750237087, 6.15665815596],
                              [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                     }
                 }]
             },
             locations=R.map(R.compose(R.pick(['id']), lambda l: l.__dict__), [R.head(self.locations)])
         )
     )
     versions = Version.objects.get_for_object(get_project_model().objects.get(
         id=R.item_str_path('data.updateProject.project.id', update_result)
     ))
     assert len(versions) == 2
def quiz_model_mutation_create(client,
                               graphql_update_or_create_function,
                               result_path,
                               values,
                               second_create_results=None,
                               second_create_does_update=False):
    """
        Tests a create mutation for a model
    :param client: The Apollo Client
    :param graphql_update_or_create_function: The update or create mutation function for the model. Expects client and input values
    :param result_path: The path to the result of the create in the data object (e.g. createRegion.region)
    :param values: The input values to use for the create
    :param second_create_results: Object, tests a second create if specified. Use to make sure that create with the same values
    creates a new instance or updates, depending on what you expect it to do.
    The values of this should be regexes that match the created instance
    :param second_create_does_update: Default False. If True expects a second create with the same value to update rather than create a new instance
    :return: Tuple with two return values. The second is null if second_create_results is False
    """
    result = graphql_update_or_create_function(client, values=values)

    result_path_partial = R.item_str_path(f'data.{result_path}')
    assert not R.has('errors', result), R.dump_json(
        R.map(lambda e: format_error(e), R.prop('errors', result)))
    # Get the created value, using underscore to make the camelcase keys match python keys
    created = R.map_keys(lambda key: underscore(key),
                         result_path_partial(result))
    # get all the keys in values that are in created. This should match values if created has everything we expect
    assert values == pick_deep(created, values)
    # Try creating with the same values again, unique constraints will apply to force a create or an update will occur
    if second_create_results:
        new_result = graphql_update_or_create_function(client, values)
        assert not R.has('errors', new_result), R.dump_json(
            R.map(lambda e: format_error(e), R.prop('errors', new_result)))
        created_too = result_path_partial(new_result)
        if second_create_does_update:
            assert created['id'] == created_too['id']
        if not second_create_does_update:
            assert created['id'] != created_too['id']
        for path, value in R.flatten_dct(second_create_results, '.').items():
            assert re.match(value, R.item_str_path_or(None, path, created_too))
    else:
        new_result = None

    return result, new_result
Beispiel #16
0
 def test_update(self):
     result, update_result = quiz_model_mutation_update(
         self.client,
         graphql_update_or_create_location,
         'createLocation.location',
         'updateLocation.location',
         dict(
             name='Grote Markt',
             key='groteMarkt',
             geojson={
                 'type': 'FeatureCollection',
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.4426671413, 5.67405195478], [50.1280516628, 5.67405195478],
                              [50.1280516628, 6.24275109216],
                              [49.4426671413, 6.24275109216], [49.4426671413, 5.67405195478]]]
                     }
                 }]
             },
             data=dict()
         ),
         # Update the coords
         dict(
             geojson={
                 'features': [{
                     "type": "Feature",
                     "geometry": {
                         "type": "Polygon",
                         "coordinates": [
                             [[49.5294835476, 2.51357303225], [51.4750237087, 2.51357303225],
                              [51.4750237087, 6.15665815596],
                              [49.5294835476, 6.15665815596], [49.5294835476, 2.51357303225]]]
                     }
                 }]
             }
         )
     )
     versions = Version.objects.get_for_object(Location.objects.get(
         id=R.item_str_path('data.updateLocation.location.id', update_result)
     ))
     assert len(versions) == 2
 def resolve_scope_instance(scope_key, user_scope_instance):
     # Replace key with id
     id = R.compose(
         # third get the id if it exists
         R.prop_or(None, 'id'),
         # second resolve the scope instance if it exists
         lambda k: R.prop_or(None, k, scope_instances_by_key),
         # first get the key
         R.item_str_path(f'{scope_key}.key'))(user_scope_instance)
     return {
         scope_key:
         R.compact_dict(
             dict(
                 # Resolve the persisted Scope instance by key
                 id=id
             ) if id else dict(
                 # Otherwise pass everything so the server can create the instance
                 # (Currently only supported for projects)
                 user_scope_instance[scope_key]))
     }
 def sample_user_state_with_search_locations_and_additional_scope_instances(
         user_scope_name, sample_user_state):
     return R.fake_lens_path_set(
         f'data.{user_scope_name}'.split('.'),
         R.map(
             lambda user_scope: R.compose(
                 # Gives applications a chance to add the needed additional scope instances,
                 # e.g. userDesignFeatures
                 lambda user_scope:
                 create_additional_scope_instance_properties(user_scope),
                 lambda user_scope: R.merge(
                     user_scope,
                     dict(userSearch=dict(userSearchLocations=R.map(
                         lambda i_search_location: dict(
                             # Just return with the id since the full data is in the database
                             searchLocation=R.pick(['id'],
                                                   i_search_location[1]),
                             # Set the first search_location to active
                             activity=dict(isActive=i_search_location[0] ==
                                           0)),
                         enumerate(search_locations))))))(user_scope),
             R.item_str_path(f'data.{user_scope_name}', sample_user_state)),
         sample_user_state)
    def test_create(self):
        # First add a new User
        margay = dict(username="******",
                      first_name='Upa',
                      last_name='Tree',
                      password=make_password("merowgir", salt='not_random'))
        user = create_sample_user(margay)

        # Now assign regions and persist the UserState
        sample_user_state_data = dict(
            user=dict(id=user.id),
            data=form_sample_user_state_data(
                self.regions,
                self.projects,
                dict(
                    userGlobal=dict(mapbox=dict(viewport=dict(
                        latitude=50.5915, longitude=2.0165, zoom=7))),
                    userRegions=[
                        dict(
                            # Assign the first region
                            region=dict(
                                key=R.prop('key', R.head(self.regions))),
                            mapbox=dict(viewport=dict(
                                latitude=50.5915, longitude=2.0165, zoom=7)),
                            userSearch=dict(userSearchLocations=R.concat(
                                R.map(
                                    lambda search_location: dict(
                                        searchLocation=R.pick(['id'],
                                                              search_location),
                                        activity=dict(isActive=True)),
                                    self.search_locations),
                                # Search locations can be created on the fly
                                [
                                    dict(searchLocation=dict(
                                        name="I am a new search"),
                                         activity=dict(isActive=True))
                                ])),
                            **self.additional_user_scope_data)
                    ],
                    userProjects=[
                        dict(
                            # Assign the first project
                            project=dict(
                                key=R.prop('key', R.head(self.projects))),
                            mapbox=dict(viewport=dict(
                                latitude=50.5915, longitude=2.0165, zoom=7)),
                            userSearch=dict(userSearchLocations=R.map(
                                lambda search_location: dict(
                                    searchLocation=R.pick(['id'],
                                                          search_location),
                                    activity=dict(isActive=True)),
                                self.search_locations)),
                            **self.additional_user_scope_data),
                        dict(
                            # Create a new project when creating the userProject
                            project=dict(user=R.pick(['id'], user),
                                         region=R.pick(['id'],
                                                       R.head(self.regions)),
                                         key='newProject',
                                         name='New Project',
                                         locations=R.map(
                                             R.pick(['id']), self.locations)),
                            mapbox=dict(viewport=dict(
                                latitude=50.5915, longitude=2.0165, zoom=7)),
                            userSearch=dict(userSearchLocations=R.map(
                                lambda search_location: dict(
                                    searchLocation=R.pick(['id'],
                                                          search_location),
                                    activity=dict(isActive=True)),
                                self.search_locations)),
                            **self.additional_user_scope_data)
                    ])))

        result, _ = quiz_model_mutation_create(
            self.client,
            R.prop('graphql_mutation', self.user_state_schema),
            'createUserState.userState',
            sample_user_state_data,
            # The second create should update, since we can only have one userState per user
            dict(),
            True)
        versions = Version.objects.get_for_object(
            UserState.objects.get(id=R.item_str_path(
                'data.createUserState.userState.id', result)))
        assert len(versions) == 1
 def extract_search_location_ids(user_regions):
     return R.map(
         R.item_str_path('searchLocation.id'),
         R.chain(R.item_str_path('userSearch.userSearchLocations'),
                 user_regions))