コード例 #1
0
    def test_shipment_udate_customer_fields(self, client_alice):
        response = client_alice.patch(self.update_url,
                                      data={
                                          'customer_fields': {
                                              'custom_field_1': 'value one',
                                              'custom_field_2': 'value two'
                                          }
                                      })
        AssertionHelper.HTTP_202(response)

        response = client_alice.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=3)
        changed_fields = self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
        assert 'customer_fields.custom_field_1' in changed_fields
        assert 'customer_fields.custom_field_2' in changed_fields

        response = client_alice.patch(
            self.update_url,
            data={'customer_fields': {
                'custom_field_2': 'new value two'
            }})
        AssertionHelper.HTTP_202(response)

        response = client_alice.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=4)
        changed_fields = self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
        assert 'customer_fields.custom_field_1' not in changed_fields
        assert 'customer_fields.custom_field_2' in changed_fields
コード例 #2
0
def test_shipment_update_with_assignee(client_alice, shipment):

    url = reverse('shipment-detail',
                  kwargs={
                      'version': 'v1',
                      'pk': shipment.id
                  })

    valid_uuid4_data = {
        'assignee_id': VALID_UUID4,
    }

    invalid_uuid4_data = {
        'assignee_id': VALID_UUID4 + '12',
    }

    # A shipment cannot be updated with an invalid assignee ID
    response = client_alice.patch(url, data=invalid_uuid4_data)
    AssertionHelper.HTTP_400(response,
                             error='Must be a valid UUID.',
                             pointer='assignee_id')

    # With a valid assignee ID the request should succeed
    response = client_alice.patch(url, data=valid_uuid4_data)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 pk=shipment.id,
                                 attributes={'assignee_id': VALID_UUID4}))
コード例 #3
0
def test_shipment_creation_with_assignee(client_alice, mocked_is_shipper,
                                         mocked_storage_credential, shipment):

    url = reverse('shipment-list', kwargs={'version': 'v1'})

    valid_uuid4_data = {
        'storage_credentials_id': shipment.storage_credentials_id,
        'shipper_wallet_id': shipment.shipper_wallet_id,
        'carrier_wallet_id': shipment.carrier_wallet_id,
        'assignee_id': VALID_UUID4,
    }

    invalid_uuid4_data = {
        'storage_credentials_id': shipment.storage_credentials_id,
        'shipper_wallet_id': shipment.shipper_wallet_id,
        'carrier_wallet_id': shipment.carrier_wallet_id,
        'assignee_id': VALID_UUID4[:-1],
    }

    # A shipment cannot be created with an invalid assignee ID
    response = client_alice.post(url, data=invalid_uuid4_data)
    AssertionHelper.HTTP_400(response,
                             error='Must be a valid UUID.',
                             pointer='assignee_id')

    # With a valid assignee ID the request should succeed
    response = client_alice.post(url, data=valid_uuid4_data)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 attributes={'assignee_id': VALID_UUID4}))
コード例 #4
0
    def test_owner_can_update_with_permission_link(self, client_alice):
        response = client_alice.patch(self.url_valid_permission,
                                      {'carriers_scac': 'carriers_scac'})
        self.entity_ref_shipment_alice.attributes = {
            'carriers_scac': 'carriers_scac'
        }

        AssertionHelper.HTTP_202(response,
                                 entity_refs=self.entity_ref_shipment_alice)
コード例 #5
0
    def test_history_filtering(self, client_alice):
        initial_datetime = datetime.now()
        one_day_later = datetime.now() + timedelta(days=1)
        two_day_later = datetime.now() + timedelta(days=2)
        # We update the shipment 1 day in the future

        with freeze_time(one_day_later.isoformat()) as date_in_future:
            response = client_alice.patch(self.update_url,
                                          {'container_qty': '1'})
            AssertionHelper.HTTP_202(response)

            # We set the clock to two days in the future
            date_in_future.move_to(two_day_later)
            response = client_alice.patch(self.update_url,
                                          {'package_qty': '10'})
            AssertionHelper.HTTP_202(response)

        response = client_alice.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=4)
        assert 'package_qty' in self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')

        response = client_alice.get(
            f'{self.history_url}?history_date__lte={initial_datetime.isoformat()}'
        )
        AssertionHelper.HTTP_200(response, is_list=True, count=2)
        assert 'package_qty' not in self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')

        response = client_alice.get(
            f'{self.history_url}?history_date__gte={initial_datetime.isoformat()}'
        )
        AssertionHelper.HTTP_200(response, is_list=True, count=2)
        assert 'package_qty' in self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
        assert 'container_qty' in self.get_changed_fields(
            response.json()['data'][1]['fields'], 'field')

        response = client_alice.get(f'{self.history_url}?history_date__lte={one_day_later.isoformat()}' \
                                    f'&history_date__gte={datetime.now().isoformat()}')
        AssertionHelper.HTTP_200(response, is_list=True, count=1)
        assert 'container_qty' in self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
コード例 #6
0
    def test_shipment_udate_location(self, client_alice):
        location_attributes, content_type = create_form_content({
            'ship_from_location.name':
            "Location Name",
            'ship_from_location.city':
            "City",
            'ship_from_location.state':
            "State",
            'ship_from_location.geometry':
            geojson.dumps(Point((42.0, 27.0)))
        })

        response = client_alice.patch(self.update_url,
                                      data=location_attributes,
                                      content_type=content_type)
        AssertionHelper.HTTP_202(response)

        response = client_alice.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=3)
        changed_fields = self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
        assert 'ship_from_location' in changed_fields
        assert 'geometry' not in self.get_changed_fields(
            response.json()['data'][0]['relationships']['ship_from_location'],
            'field')
        assert 'ship_from_location' in response.json(
        )['data'][0]['relationships'].keys()

        location_attributes, content_type = create_form_content(
            {'ship_from_location.phone_number': '555-555-5555'})

        response = client_alice.patch(self.update_url,
                                      data=location_attributes,
                                      content_type=content_type)
        AssertionHelper.HTTP_202(response)

        response = client_alice.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=4)
        ship_from_location_changes = response.json(
        )['data'][0]['relationships']['ship_from_location']
        assert 'phone_number' in self.get_changed_fields(
            ship_from_location_changes, 'field')
コード例 #7
0
def test_geofence_creates(client_alice, mocked_iot_api, mocked_profiles,
                          mocked_engine_rpc, profiles_ids,
                          successful_shipment_create_profiles_assertions):
    url = reverse('shipment-list', kwargs={'version': 'v1'})
    shipment_create_request = {"geofences": [GEOFENCE_3], **profiles_ids}
    response = client_alice.post(url, data=shipment_create_request)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 attributes=shipment_create_request))
    mocked_profiles.assert_calls(
        successful_shipment_create_profiles_assertions)
コード例 #8
0
def test_geofence_updates(client_alice, shipment_with_device, shipment):
    url = reverse('shipment-detail',
                  kwargs={
                      'version': 'v1',
                      'pk': shipment_with_device.id
                  })
    shipment_update_request = {'geofences': [GEOFENCE_1]}
    response = client_alice.patch(url, data=shipment_update_request)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 pk=shipment.id,
                                 attributes=shipment_update_request))

    shipment_update_request_formdata, content_type = create_form_content({
        "geofences":
        json.dumps([GEOFENCE_2]),
    })
    response = client_alice.patch(url,
                                  data=shipment_update_request_formdata,
                                  content_type=content_type)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 pk=shipment.id,
                                 attributes={'geofences': [GEOFENCE_2]}))

    # Test shipment without a device
    url = reverse('shipment-detail',
                  kwargs={
                      'version': 'v1',
                      'pk': shipment.id
                  })
    shipment_update_request = {'geofences': [GEOFENCE_3]}
    response = client_alice.patch(url, data=shipment_update_request)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 pk=shipment.id,
                                 attributes=shipment_update_request))
コード例 #9
0
    def assert_write_access(self,
                            client,
                            shipment_access=None,
                            tags_access=None,
                            documents_access=None,
                            notes_access=None,
                            all_access=None):
        if all_access is not None:
            shipment_access = all_access
            tags_access = all_access
            documents_access = all_access
            notes_access = all_access

        shipment_data = {'carriers_scac': 'h4x3d'}
        tag_data = {
            'tag_type': 'foo',
            'tag_value': 'bar',
            'owner_id': client.handler._force_user.id,
        }
        document_data = {
            'name': 'Test BOL',
            'file_type': 'PDF',
            'document_type': 'AIR_WAYBILL'
        }
        note_data = {'message': 'hello, world.'}

        if shipment_access is not None:
            response = client.patch(self.endpoint_urls['shipment'],
                                    shipment_data)
            AssertionHelper.HTTP_202(
                response) if shipment_access else AssertionHelper.HTTP_403(
                    response)

        if tags_access is not None:
            response = client.post(self.endpoint_urls['tags'], tag_data)
            AssertionHelper.HTTP_201(
                response) if tags_access else AssertionHelper.HTTP_403(
                    response)

        if documents_access is not None:
            response = client.post(self.endpoint_urls['documents'],
                                   document_data)
            AssertionHelper.HTTP_201(
                response) if documents_access else AssertionHelper.HTTP_403(
                    response)

        if notes_access is not None:
            response = client.post(self.endpoint_urls['notes'], note_data)
            AssertionHelper.HTTP_201(
                response) if notes_access else AssertionHelper.HTTP_403(
                    response)
コード例 #10
0
    def test_rw_shipment_no_tags_on_update(self, shipment_alice, client_bob,
                                           new_rw_access_request_bob,
                                           entity_ref_shipment_alice):
        new_rw_access_request_bob.tags_permission = PermissionLevel.NONE
        new_rw_access_request_bob.approved = True
        new_rw_access_request_bob.save()

        response = client_bob.patch(self.endpoint_urls['shipment'],
                                    {'carriers_scac': 'h4x3d'})
        AssertionHelper.HTTP_202(response,
                                 entity_refs=entity_ref_shipment_alice)
        assert 'tags' not in response.json()['data']['relationships']
        for included in response.json()['included']:
            assert included['type'] != 'ShipmentTag'
コード例 #11
0
    def test_with_permission_links(self, shipment_alice, client_bob,
                                   new_rw_access_request_bob,
                                   permission_link_shipment_alice):
        shipment_data = {'carriers_scac': 'h4x3d'}
        tag_data = {
            'tag_type': 'foo',
            'tag_value': 'bar',
            'owner_id': client_bob.handler._force_user.id,
        }

        # Documents/notes are not accessible via permission link, tracking/telemetry is RO
        response = client_bob.get(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}'
        )
        AssertionHelper.HTTP_200(
            response,
            entity_refs=AssertionHelper.EntityRef(
                resource='Shipment',
                relationships={
                    'tags':
                    AssertionHelper.EntityRef(resource='ShipmentTag',
                                              pk=self.tag.id)
                }),
            included=AssertionHelper.EntityRef(resource='ShipmentTag'),
        )

        response = client_bob.patch(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}',
            shipment_data)
        AssertionHelper.HTTP_403(response)

        response = client_bob.post(
            f'{self.endpoint_urls["tags"]}?permission_link={permission_link_shipment_alice.id}',
            tag_data)
        AssertionHelper.HTTP_403(response)

        new_rw_access_request_bob.approved = True
        new_rw_access_request_bob.save()

        response = client_bob.patch(
            f'{self.endpoint_urls["shipment"]}?permission_link={permission_link_shipment_alice.id}',
            shipment_data)
        AssertionHelper.HTTP_202(response)

        response = client_bob.post(
            f'{self.endpoint_urls["tags"]}?permission_link={permission_link_shipment_alice.id}',
            tag_data)
        AssertionHelper.HTTP_201(response)
コード例 #12
0
def test_geofence_dedup(client_alice, shipment_with_device):
    # Check geofence_id uniqueness
    url = reverse('shipment-detail',
                  kwargs={
                      'version': 'v1',
                      'pk': shipment_with_device.id
                  })
    shipment_update_request = {
        'geofences': [
            GEOFENCE_1, GEOFENCE_2, GEOFENCE_2, GEOFENCE_3, GEOFENCE_3,
            GEOFENCE_3
        ]
    }
    response = client_alice.patch(url, data=shipment_update_request)
    AssertionHelper.HTTP_202(response)

    updated_parameters = response.json()['data']['attributes']
    assert sorted(updated_parameters['geofences']) == sorted(
        [GEOFENCE_1, GEOFENCE_2, GEOFENCE_3])
コード例 #13
0
    def test_shipment_udate_fields(self, client_bob,
                                   mock_successful_wallet_owner_calls,
                                   user_bob_id):
        response = client_bob.patch(self.update_url,
                                    data={
                                        'carriers_scac': 'carrier_scac',
                                        'pickup_act': datetime.utcnow()
                                    })
        AssertionHelper.HTTP_202(response)
        mock_successful_wallet_owner_calls.assert_calls(self.assert_success)

        response = client_bob.get(self.history_url)
        AssertionHelper.HTTP_200(response, is_list=True, count=3)
        mock_successful_wallet_owner_calls.assert_calls(self.assert_success)
        changed_fields = self.get_changed_fields(
            response.json()['data'][0]['fields'], 'field')
        assert 'carriers_scac' in changed_fields
        assert 'updated_by' in changed_fields
        assert 'pickup_act' not in changed_fields

        assert response.json()['data'][0]['author'] == user_bob_id
コード例 #14
0
def test_protected_shipment_date_updates(client_alice, shipment):
    url = reverse('shipment-detail',
                  kwargs={
                      'version': 'v1',
                      'pk': shipment.id
                  })

    start_date = datetime.utcnow().replace(tzinfo=pytz.UTC) - relativedelta(
        years=1)
    parameters = {
        'pickup_est': start_date.isoformat(),
        'pickup_act': (start_date + relativedelta(days=1)).isoformat(),
        'port_arrival_est': (start_date + relativedelta(days=2)).isoformat(),
        'port_arrival_act': (start_date + relativedelta(days=3)).isoformat(),
        'delivery_est': (start_date + relativedelta(days=4)).isoformat(),
        'delivery_act': (start_date + relativedelta(days=5)).isoformat(),
    }
    # Assert that none of the values to be updated already exist
    for field in parameters:
        assert getattr(shipment, field) != parameters[field], f'Field: {field}'

    response = client_alice.patch(url, data=parameters)
    AssertionHelper.HTTP_202(response,
                             entity_refs=AssertionHelper.EntityRef(
                                 resource='Shipment',
                                 pk=shipment.id,
                             ))
    updated_parameters = response.json()['data']['attributes']

    # Assert that only the updatable fields got updated
    for field in parameters:
        if '_act' in field:
            assert updated_parameters[field] is None, f'Field: {field}'
        else:
            assert dt_parse(parameters[field]) == dt_parse(
                updated_parameters[field]), f'Field: {field}'
コード例 #15
0
 def test_can_create(self, client_alice, mocked_engine_rpc):
     self.base_call['tags'] = [
         {
             'tag_value': 'tag_value',
             'tag_type': 'tag_type'
         }, {
             'tag_value': 'tag_value_two',
             'tag_type': 'tag_type'
         },
     ]
     response = client_alice.post(self.url, self.base_call)
     AssertionHelper.HTTP_202(response, included=[
         AssertionHelper.EntityRef(resource='ShipmentTag',
                                   attributes={
                                       'tag_type': 'tag_type',
                                       'tag_value': 'tag_value'
                                   }),
         AssertionHelper.EntityRef(resource='ShipmentTag',
                                   attributes={
                                       'tag_type': 'tag_type',
                                       'tag_value': 'tag_value_two'
                                   })
     ])
     self.wallet_mocking.assert_calls(self.assertions)
コード例 #16
0
    def test_update_shipment_device_certificate(
            self, client_alice, tracking_data, profiles_ids, mocker,
            shipment_alice_with_device, mock_successful_wallet_owner_calls,
            successful_shipment_create_profiles_assertions):
        mock_device_call = mocker.patch.object(settings.REQUESTS_SESSION,
                                               'get')
        mock_device_call.return_value.status_code = 200

        with open('tests/data/cert.pem', 'r') as cert_file:
            cert_pem = cert_file.read()

        map_describe = {}
        principals = []
        for i in range(0, 4):
            describe = {}
            res = self.mocked_iot.create_keys_and_certificate()
            describe['certificateDescription'] = res
            describe['certificateDescription']['status'] = 'INACTIVE'
            if i == 1:
                expired_certificate = res['certificateId']
            if i == 2:
                describe['certificateDescription']['status'] = 'ACTIVE'
                describe['certificateDescription']['certificatePem'] = cert_pem
                new_active_certificate = res['certificateId']
            map_describe[res['certificateId']] = describe
            principals.append(res['certificateArn'])

        self.device.certificate_id = expired_certificate
        self.device.save()

        def side_effects(**kwargs):
            cert = kwargs['certificateId']
            return map_describe[cert]

        with mock.patch('apps.shipments.serializers.boto3.client') as serial_client, \
                mock.patch('apps.shipments.models.boto3.client') as model_client:
            serial_client = serial_client.return_value
            model_client = model_client.return_value
            serial_client.describe_certificate.side_effect = side_effects
            model_client.list_thing_principals.return_value = {
                'principals': principals
            }
            model_client.describe_certificate.side_effect = side_effects

            signed_data = self.sign_tracking(
                tracking_data,
                self.device,
                certificate_id=new_active_certificate)
            response = client_alice.post(self.url_device,
                                         data={'payload': signed_data})
            AssertionHelper.HTTP_204(response)
            self.device.refresh_from_db()

            assert self.device.certificate_id == new_active_certificate
            shipment_alice_with_device.device = None
            shipment_alice_with_device.save()

            self.device.certificate_id = expired_certificate
            self.device.save()
            self.device.refresh_from_db()

            response = client_alice.post(self.create_url,
                                         data={
                                             'device_id': self.device.id,
                                             **profiles_ids
                                         })
            AssertionHelper.HTTP_202(response)

            self.device.refresh_from_db()
            assert self.device.certificate_id == new_active_certificate