How do i mock an attribute within nested constructor using unittest - python-3.x

This is what i am trying to test :
src/DBOps.py
class DBOps() :
class dynamodbOps() :
def __init__(self,db_table) :
dynamodb = boto3.resource('dynamodb')
self.table = dynamodb.Table(db_table)
def GetDBItem(self,pool):
response = self.table.get_item(Key={'pool' : pool})
And this is the test case that is unsuccessful :
class test_GetDBItem(unittest.TestCase) :
def setUp(self):
self.db_ops = DBOps()
db_table = "test_table"
self.dyn = self.db_ops.dynamodbOps(db_table)
#mock.patch('src.DBOps')
def test_run_query_with_item(self, getItem_mock) :
getItem_mock.dynamodbOps.table.get_item.return_value = {"Blah":"Blah Blah"}
pool = 'some_pool'
response = self.dyn.GetDBItem(pool)
I am trying to mock the 'table.get_item' call and failing at it no matter what i try. Any pointers would be great!

Figured it out as below :
class test_GetDBItem(unittest.TestCase) :
def setUp(self):
db_ops = DBOps()
db_table = "test_table"
self.dyn = db_ops.dynamodbOps(db_table)
def test_run_query_with_item(self) :
with patch.object(self.dyn.table, 'get_item') as getItem_mock :
getItem_mock.return_value = {"Blah":"Blah Blah"}
pool = 'some pool'
response = self.dyn.GetDBItem(quadra_pool)

Related

Why I am getting this error? pydantic.error_wrappers.ValidationError: 2 validation errors for DishMenus

model.py
class Dish(db.Entity):
id = PrimaryKey(UUID, auto=True)
dish_name = Required(str, unique =True)
price = Required(float, default=0)
created_at = Required(date)
dish_menus = Set('Dish_Menu')
class Menu(db.Entity):
id = PrimaryKey(UUID, auto=True)
date = Required(date)
dish_menu = Set('Dish_Menu')
class Dish_Menu(db.Entity):
id = PrimaryKey(UUID, auto=True)
dish_availability = Required(int)
dishes = Required("Dish", column = "dish_id")
menus = Required("Menu", column = "menu_id")
routes.py
#api.post('/', status_code=status.HTTP_201_CREATED)
async def create_dish_menu(dish_menu: DishMenus):
with db_session:
new_dish = Dish_Menu(dish_availability = dish_menu.dish_availability,
dishes = dish_menu.dish_id, menus = dish_menu.menu_id)
commit()
result = SaveDishMenu.from_orm(new_dish)
return result
#api.get('/', status_code=status.HTTP_200_OK)
async def get_all_dish_menu():
with db_session:
dish_menu = Dish_Menu.select()
print(dish_menu);
result = [DishMenuDetails.from_orm(i) for i in dish_menu]
return result
schemas.py
class SaveDishMenu(BaseModel):
id : Optional [UUID]
dish_availability: int
class Config:
orm_mode = True
class DishMenus(SaveDishMenu):
dish_id : str
menu_id : str
class Config:
orm_mode = True
class DishMenuDetails(SaveDishMenu):
dish_id : DishDetails
menu_id : MenuSchema
I can post a dish menu, but I have problem in getting all of those input because I'm getting this error: pydantic.error_wrappers.ValidationError: 2 validation errors for DishMenus dish_id field required (type=value_error.missing) menu_id field required (type=value_error.missing)
In my schemas, I inherit some because of some factors. Do I need to change something on my model? or route?
Can someone help me with it? Thanks

How to capture a field instance during django-import-export upload

I'd like to import data into my resource minus the school field because the logged in user already belongs to a specific school. How would I do it without having the school field in my excel???
class uploadStudents(LoginRequiredMixin,View):
context = {}
def get(self,request):
form = UploadStudentsForm()
self.context['form'] = form
return render(request,'upload.html',self.context)
def post(self, request):
form = UploadStudentsForm(request.POST , request.FILES)
data_set = Dataset()
if form.is_valid():
file = request.FILES['file']
extension = file.name.split(".")[-1].lower()
resource = ImportStudentsResource()
if extension == 'csv':
data = data_set.load(file.read().decode('utf-8'), format=extension)
else:
data = data_set.load(file.read(), format=extension)
result = resource.import_data(data_set, dry_run=True, collect_failed_rows=True, raise_errors=True)
if result.has_validation_errors() or result.has_errors():
messages.success(request,f'Errors experienced during import.')
print("error", result.invalid_rows)
self.context['result'] = result
return redirect('import_students')
else:
result = resource.import_data(data_set, dry_run=False, raise_errors=False)
self.context['result'] = None
messages.success(request,f'Students uploaded successfully.')
else:
self.context['form'] = UploadStudentsForm()
return render(request, 'upload.html', self.context)
The resource
class ImportStudentsResource(resources.ModelResource):
school = fields.Field(attribute = 'school',column_name='school', widget=ForeignKeyWidget(School, 'name'))
klass = fields.Field(attribute = 'klass',column_name='class', widget=ForeignKeyWidget(Klass, 'name'))
stream = fields.Field(attribute = 'stream',column_name='stream', widget=ForeignKeyWidget(Stream, 'name'))
class Meta:
model = Student
fields = ('school','student_id','name','year','klass','stream')
import_id_fields = ('student_id',)
import_order = ('school','student_id','name','year','klass','stream')
Either remove 'school' from your 'fields' declaration, or add it to the 'exclude' list.
docs
Edit
To include a school_id which is associated with the logged in user, you'll need to create the Resource with this school_id:
Resource
class ImportStudentsResource(resources.ModelResource):
def __init__(self, school_id):
super().__init__()
self.school_id = school_id
def before_save_instance(self, instance, using_transactions, dry_run):
instance.school_id = self.school_id
post()
def post(self, request):
# skipped existing code
school_id = get_school_id_from_logged_in_user(self.request)
resource = ImportStudentsResource(school_id)

Access app_context from custom Converter in Quart

Is there a solution to get the app context in a class that inherit werkzeug BaseConverter class?
This is my example running in Flask:
from werkzeug.routing import BaseConverter
class CodeConverter(BaseConverter):
app = None
def to_python(self, value):
# Create an app context to get value from db
# and instantiate a class X as obj
return obj
def to_url(self, obj):
value = obj.code
title = obj.title
return "%s/%s"%(value, title)
def crate_app():
...
app.url_map.converters['code'] = CodeConverter
CodeConverter.app = app
...
Well, this works for me.
from werkzeug.routing import BaseConverter
class CodeConverter(BaseConverter):
app = None
async def get_object(self, app, value):
async with app.app_context():
# and instantiate a class X as obj
return obj
def to_python(self, value):
pool = concurrent.futures.ThreadPoolExecutor()
result = pool.submit(asyncio.run, self.get_object(self.__class__.app, value)).result()
return result
def to_url(self, obj):
value = obj.code
title = obj.title
return "%s/%s"%(value, title)
def crate_app():
...
app.url_map.converters['code'] = CodeConverter
CodeConverter.app = app
...

Trying to mock two classes with Groovy Spock Mock: GroovyCastException

I try to mock two classes in a Jenkins Pipeline var-script, but however I order the definition of the Mock I receive a GroovyCastException, while the mock for the second class is initiated
org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'Mock for type 'ClassA'' with class 'com.pipeline.ClassA$$EnhancerByCGLIB$$9b005c28' to class 'com.pipeline.DBReader'
This is how my Spock-Test looks like:
import com.homeaway.devtools.jenkins.testing.JenkinsPipelineSpecification
import com.pipeline.ClassA
import com.pipeline.DBReader
import groovy.sql.Sql
import org.jenkinsci.plugins.workflow.steps.FlowInterruptedException
import hudson.model.Result
class execScriptSpec extends JenkinsPipelineSpecification {
def execPipelineScript = null
def mockStage = [timeout: [time: 'mocktime']]
def mockScript = [...]
def setup() {
execPipelineScript = loadPipelineScriptForTest("vars/execScript.groovy")
}
def "Test Pipeline-Script"() {
setup:
GroovyMock(ClassA, global: true)
new ClassA(*_) >> Mock(ClassA) {
loadScope(_) >> null
loadJsonFromURL(_) >> null
}
GroovyMock(DBReader, global: true)
new DBReader(*_) >> Mock(DBReader) {
loadDBDriver(_) >> null
}
when:
execPipelineScript(mockScript, mockStage)
then:
true
And that is the code under test:
import com.pipeline.DBReader
import com.pipeline.ClassA
def call(script, stage) {
def pipelineConfig = script.pipelineConfig
def stageStatus = pipelineConfig.general.stageStatus
def projectName = script.env.project
// DB connection parameters
def dbName = script.deliveryConfig.system.dbName
def dbSchema = script.deliveryConfig.system.dbSchema
def dbServer = script.deliveryConfig.system.dbServer
def dbUser = script.deliveryConfig.system.dbUser
// DB Driver to use
def dbDriver = script.deliveryConfig.system.dbDriver
def dbPassword = script.env.password
// Create new DB-Client
DBReader dbClient = new DBReader(dbName, dbSchema, dbServer, dbUser, dbPassword, dbDriver)
dbClient.loadDBDriver()
def contextParameter = script.params['Context']
ClassA mapGavToVersionRange = new ClassA(projectName, contextParameter, script)
classAInstance.loadDeliveryScope( dbClient )
def url = 'https://some.valid.url'
classAInstance.loadJsonFromURL(url)
...
So don't get me wrong: The actual mocking of one or the other class works (if I put only one of them in my test), but as soon as I put both of them, the second one will not work. And I currently have no idea, why this happens.
Would be great, if anybody has an idea :-)
Thanks a lot!

Initializing AssetManager in Groovy Console

My goal is to programmatically move assets. I have found that AssetManager has a moveAsset method. However, I am having issues initializing an AssetManager object in my groovy script. Below is the code I am working with. How do I initialize a non-null AssetManager object?
import javax.jcr.query.*
import com.day.cq.dam.api.*
def query = createSQL2Query("/content/dam/3d-renders/application-notes/wcc-migration") //CHANGE THIS
def result = query.execute()
def rows = result.rows
rows.each { row ->
Resource res = resourceResolver.getResource(null,row.path)
AssetManager am = res.adaptTo(AssetManager.class)
am.getAsset('/content/dam/3d-renders/application-notes/wcc-migration/Q60_ILL000347_iAPP.psd')
println res.path + ' ' + am
//am.moveAsset('/content/dam/3d-renders/application-notes/wcc-migration/2015/Q3X-Color-Mark-Sensing.psd','/content/dam/3d-renders/test-folder/Q3X-Color-Mark-Sensing.psd')
}
def createSQL2Query(startPage) {
def queryManager = session.workspace.queryManager
def statement = "select * from [nt:base] as p where (isdescendantnode (p, '$startPage')) and p.[jcr:primaryType] = 'dam:Asset'"
def query = queryManager.createQuery(statement, Query.JCR_SQL2)
query
}
Try getting your asset manager like this:
AssetManager am = resourceResolver.adaptTo(AssetManager.class)
ResourceResolver implements Adaptable, the interface where the adaptTo(Class) method is defined.

Resources