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
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
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)
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
...
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!
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.